Guide

npm Proxy Settings and Errors: .npmrc, HTTPS_PROXY and SOCKS, Tested

npm proxy settings, tested on npm 11.8 and 10.9: https-proxy and proxy, HTTP_PROXY, noproxy, SOCKS5, E407, ECONNRESET and the certificate errors.

HProxy Team··Updated September 27, 2026·15 min read
HProxy.Guide

Skip the dead lists.

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump.

Open the free proxy list→

When npm cannot reach its registry, the error often ends with a paragraph about proxies. That paragraph comes with some errors and not with others. The line that names the problem is the one that starts with npm error code.

We tested how npm handles a proxy on 27 September 2026, with npm 11.8.0 and with npm 10.9.3, the version bundled with Node 22.19. The proxies ran on our own machine. The registry was a made-up host that only those proxies could reach, so every request either went through a proxy or failed at once. We ran 42 setups on both versions, twice, and got the same results every time. More tests covered the npm config commands, a proxy that never answers and the real registry. npm 12 was not run, but it ships the same proxy code, as How we tested explains.

The short version:

  • Set https-proxy to an address that starts with http://. npm uses https-proxy when it is set and proxy otherwise, for every request.
  • HTTP_PROXY does not cover the registry. For https:// addresses npm reads HTTPS_PROXY, and --proxy=false does not switch that off.
  • npm config get shows only npm's own settings. It prints null while HTTPS_PROXY is set, and it refuses to print an address that holds a password.
  • With SOCKS, write socks5h://. With socks5://, npm looks up the registry name on your own machine first.
  • For a company certificate, use NODE_EXTRA_CA_CERTS. The cafile setting replaces npm's whole list of trusted authorities.

Read the npm error code line

Since npm 10.6.0, released in April 2024, every error line starts with npm error. Older versions printed npm ERR!. When npm cannot find the registry, npm 11.8.0 ends like this:

npm error code ENOTFOUND
npm error syscall getaddrinfo
npm error errno ENOTFOUND
npm error network request to https://registry.lab.test/lab-pkg failed, reason: getaddrinfo ENOTFOUND registry.lab.test
npm error network This is a problem related to network connectivity.
npm error network In most cases you are behind a proxy or have bad network settings.
npm error network
npm error network If you are behind a proxy, please make sure that the
npm error network 'proxy' config is set properly.  See: 'npm help config'

In our tests the paragraph about proxies came with two codes, ENOTFOUND and ECONNRESET. After ECONNREFUSED, npm printed its last two lines below a stack trace. The login error, the certificate errors and the rest came without it. Read the code line. This is what caused each one in our tests:

  • ENOTFOUND: no proxy was used, and the name did not resolve. Set https-proxy.
  • E407: the proxy wants a login. Add the login to the address.
  • ECONNRESET: the proxy cut the connection. Test the proxy on its own.
  • ECONNREFUSED: nothing listens at the proxy address. Fix or remove the setting.
  • EPROTO: https:// in front of a plain proxy. Write http://.
  • EINVALIDPROXY: an address without http://. Add it.
  • FETCH_ERROR: a SOCKS proxy wants a login. Add the login to the address.
  • No error and no end: the proxy never answers. Stop npm and test the proxy.

The certificate codes have their own section below.

ENOTFOUND: npm went direct

getaddrinfo ENOTFOUND means the name lookup failed. Node's documentation calls it "a DNS failure". In our tests it meant npm had not used a proxy at all. Either none was set, or only HTTP_PROXY or ALL_PROXY was set, or a noproxy entry matched, or the proxy address started with socks5:// or socks4://. On a network where only the proxy reaches the internet, you get this error until npm uses the proxy. The next section shows which settings count.

E407: the proxy wants a login

npm error code E407
npm error 407 Proxy Authentication Required - GET https://registry.lab.test/lab-pkg

npm printed these two lines and the path of its log, and nothing else. The fix is a login in the proxy address. Our guide to 407 Proxy Authentication Required covers the same error in other tools.

ECONNRESET: something cut the connection

One of our proxies cut the connection when npm asked for a tunnel. Another cut it during the encrypted handshake that follows. Both gave the same line, followed by the paragraph about proxies:

npm error network request to https://registry.lab.test/lab-pkg failed, reason: read ECONNRESET

Node's documentation describes the code as "A connection was forcibly closed by a peer." npm cannot tell you which step failed, or whether a proxy did it. Test the proxy address outside npm first:

curl -v -x http://proxy.example.com:3128 https://registry.npmjs.org/

If curl gets through and npm does not, compare the settings in the next section. A popular Stack Overflow answer suggests switching the registry to http://. Today the registry answers every plain http:// request with a redirect to https://: we checked the registry root, a package and a tarball. So the switch no longer avoids the encrypted connection. It adds an unencrypted first request that the network can read and change, and it hides the cause.

ECONNREFUSED: nothing at that address

The line to read is connect ECONNREFUSED 127.0.0.1:<port>, with the address and port from your setting. That address is the proxy's, and nothing listened there. npm printed a stack trace and the last two lines of the proxy paragraph.

An address on 127.0.0.1 points at your own machine: a program there was meant to answer, and none did. npm takes its proxy from its own settings or, for the https:// registry, from HTTPS_PROXY, so the old address sits in one of those. Checking shows how to find it. How to turn off a proxy covers the proxy settings of the system itself.

A proxy that never answers

One of our proxies accepted the connection, read npm's request for a tunnel, and stayed silent. npm printed nothing and did not stop. With the default timeouts, npm 11.8.0 and npm 10.9.3 were both still waiting after 10 minutes. That is twice the default fetch-timeout of 5 minutes. Setting fetch-timeout to 5 seconds changed nothing within a minute.

npm's code explains why. fetch-timeout becomes a timer on the connection, and npm starts it only after the proxy has opened the tunnel. The step before that has no limit: its connection timeout is set to 0. If npm hangs without an error, stop it with Ctrl+C and test the proxy with curl as above.

We did not produce ETIMEDOUT, because our tests never left the machine. Node's documentation describes it as "A connect or send request failed because the connected party did not properly respond after a period of time." The same curl test shows whether the proxy address answers at all.

EPROTO and EINVALIDPROXY: the start of the address

With https:// in front of an ordinary proxy, npm tried to open an encrypted connection to the proxy itself. The proxy answered in plain text, and npm stopped with EPROTO and wrong version number. Write http:// for https-proxy too, unless your proxy's documentation says it takes encrypted connections.

Without any scheme, as in localhost:8080, npm stopped at once:

npm error code EINVALIDPROXY
npm error Invalid protocol `localhost:` connecting to proxy ``

npm read localhost: as the scheme. Put http:// in front.

Which setting npm uses

npm has two proxy settings, https-proxy and proxy, and it also reads the environment. This is what reached our proxy when npm fetched from an https:// registry:

SetupThrough the proxy?
https-proxy (flag or .npmrc)Yes
proxy onlyYes
HTTPS_PROXYYes
HTTP_PROXY onlyNo, npm went direct
ALL_PROXY onlyNo, npm went direct
HTTPS_PROXY with proxy=falseYes, still
noproxy naming the registryNo, skipped
noproxy=lab.testNo, skipped
noproxy=*.lab.testYes, still
NO_PROXY=*Yes, still

npm's documentation says proxy is for http requests and that HTTP_PROXY is honoured for https requests. Neither matched what npm did, and the code explains both. npm hands one proxy to every request: https-proxy when it is set, and proxy otherwise. Only when both are empty does npm read the environment. For an https:// address it then reads HTTPS_PROXY alone, in any letter case. A setting of false counts as empty, which is why --proxy=false did not stop HTTPS_PROXY.

noproxy takes a list separated by commas. npm compares whole parts of the host name, starting from the right, so lab.test covered registry.lab.test. A star is not a wildcard in npm: *.lab.test and NO_PROXY=* changed nothing. List the domains themselves:

npm config set noproxy "localhost,127.0.0.1,corp.example.com"
Our own console window: the npm proxy lab of 27 September 2026 on Node 22.19. With no proxy, only HTTP_PROXY, only ALL_PROXY or a matching noproxy entry, the proxy saw nothing and npm failed with ENOTFOUND. https-proxy, proxy alone, HTTPS_PROXY and HTTPS_PROXY with --proxy=false went through a CONNECT tunnel. Logins worked with @ as %40 and left raw. Proxies that cut the connection gave ECONNRESET, a silent proxy left npm waiting, an address without http:// gave EINVALIDPROXY. socks5:// and socks4:// never reached the proxy, while socks5h://, socks:// and socks4a:// passed the host name. The three certificate chains gave three codes, and cafile with only the proxy root rejected the normal registry. npm 10.9.3 gave the same result in all 42 setups.
Captured on our own machine on 27 September 2026: npm 11.8.0 results from our second run. The lab password is masked and ports read <port>.

Set, check and remove a proxy

Set both keys to the same address. They land in your user .npmrc, which is ~/.npmrc, or C:\Users\<you>\.npmrc on Windows:

npm config set https-proxy http://user:pass@proxy.example.com:3128
npm config set proxy http://user:pass@proxy.example.com:3128

Each command writes one line into the file. In our test, npm config set proxy http://proxy.example.com:3128 and npm config set https-proxy http://alice:p%40ss@proxy.example.com:3128 left exactly this:

proxy=http://proxy.example.com:3128
https-proxy=http://alice:p%40ss@proxy.example.com:3128

You can also write these lines into the file yourself. A project can carry its own .npmrc in its folder, and npm also has a global one. npm config list shows each value under the file it came from. It showed our password as ***. npm config list -l adds every default, 186 lines in npm 11.8.0.

npm config get can mislead in two ways:

  • npm config get https-proxy prints null when the proxy comes from HTTPS_PROXY. It shows npm's own settings only.
  • When the address holds a password, npm config get refuses to print it: "The https-proxy option is protected, and cannot be retrieved in this way". Read it with npm config list, or open the .npmrc file.

The environment needs its own check. Since npm 11.8.0, released in January 2026, npm config list shows proxy variables in a block called environment-related config. npm 10.9.3 does not show them. That block printed our test password in plain text, while the same password from .npmrc showed as ***. Look at it before you paste the output anywhere. You can also ask the shell:

  • PowerShell: Get-ChildItem Env:*proxy*
  • Command Prompt: set | findstr /i proxy
  • macOS and Linux: env | grep -i proxy

A variable named npm_config_https_proxy is an npm setting in the environment. npm config get and npm config list both show it.

To remove the proxy:

npm config delete https-proxy
npm config delete proxy

npm config rm does the same. Once the last setting was gone, npm deleted the .npmrc file. npm config set proxy false does not remove anything: it writes proxy=false into the file, and a proxy in HTTPS_PROXY stays in use, as the table shows. Remove the variable as well. For the current window, run Remove-Item Env:HTTPS_PROXY in PowerShell, set HTTPS_PROXY= in Command Prompt with nothing after the equals sign (a space there sets the variable to a space), or unset HTTPS_PROXY https_proxy elsewhere. For good, delete it in the system settings or your shell profile.

A login in the proxy address

npm takes the login from the address, http://user:pass@proxy.example.com:3128. In our tests it sent the login with its first request to the proxy, as Basic authentication.

A password with @ worked in both forms, written as %40 and left as it is. The raw form works because the last @ ends the login. Other characters need the percent form. In Node's URL parser, which npm's proxy code uses, a raw # broke the whole address, while %23 worked. Node prints the percent form for you:

node -e "console.log(encodeURIComponent('p@ss#1'))"

That prints p%40ss%231. A missing or wrong login gives E407.

We did not test proxies that accept only Windows logins (NTLM or Kerberos).

SOCKS proxies

npm accepts SOCKS addresses in https-proxy, proxy and HTTPS_PROXY. The letters after socks decide who looks up the registry's name:

  • socks5h://, socks:// and socks4a://: npm passes the name to the proxy. Our proxy received registry.lab.test, and all three worked.
  • socks5:// and socks4://: npm looks the name up on your machine first. registry.lab.test exists only behind our proxy, so npm stopped with ENOTFOUND before it contacted the proxy. With a name that does resolve here, localhost, the proxy received an address instead of a name.

The code of the SOCKS agent that npm uses says it in a comment: "Client-side DNS resolution for "4" and "5" socks proxy versions." On a network where your machine cannot look up outside names, only the forms that pass the name get through: socks5h://, socks:// and socks4a://. With socks5://, your own DNS server also sees every host npm contacts.

npm config set https-proxy socks5h://user:pass@proxy.example.com:1080

A login in the address worked, with @ written as %40. When our SOCKS proxy wanted a login and got none, npm printed FETCH_ERROR and "Received invalid Socks5 initial handshake (no accepted authentication type)". Our SOCKS5 guide explains the protocol.

Certificate errors from an inspecting proxy

Some company proxies open HTTPS to look inside it, then sign the connection again with the company's own certificate authority. npm does not trust that authority. The error code depends on what the proxy sends along with its certificate:

  • Only its own certificate: UNABLE_TO_VERIFY_LEAF_SIGNATURE, "unable to verify the first certificate".
  • Its certificate and the company root: SELF_SIGNED_CERT_IN_CHAIN, "self-signed certificate in certificate chain".
  • Its certificate and an intermediate: UNABLE_TO_GET_ISSUER_CERT_LOCALLY, "unable to get local issuer certificate".

OpenSSL's documentation fits each shape. For the second one, it says the chain "could be built up using the untrusted certificates but no suitable trust anchor (which typically is a self-signed root certificate) could be found in the trust store."

All three have one fix: trust the company's root certificate. Ask IT for it, or export it from the system certificate store as a PEM file. Two settings take it, and they behave differently:

  • NODE_EXTRA_CA_CERTS adds the root to Node's built-in list, for npm and every other Node program. With it, npm worked through the inspecting proxy and through a plain proxy to the normal registry.
  • npm config set cafile replaces npm's whole list with the file. It fixed the inspecting proxy. With only the company root in the file, though, npm rejected the normal registry. In our lab, whose registry sent only its own certificate, the code was UNABLE_TO_VERIFY_LEAF_SIGNATURE. Against the real registry, registry.npmjs.org, with no proxy in between, npm 11.8.0 and 10.9.3 both stopped with UNABLE_TO_GET_ISSUER_CERT_LOCALLY. That is the position of a laptop that leaves the company network, and it is the same code an inspecting proxy can give. When it appears away from the company network, check whether cafile is set before you look for a proxy.

npm's own documentation says a specific certificate in its ca setting means you "trust only that specific signing authority". Setting both does not help either. With cafile set, npm ignored the root we had put in NODE_EXTRA_CA_CERTS. Node's documentation says why: "Neither the well known nor extra certificates are used when the ca options property is explicitly specified". NODE_EXTRA_CA_CERTS alone is the simpler choice. Set it once for your user:

setx NODE_EXTRA_CA_CERTS C:\certs\company-root.pem

On macOS and Linux, put export NODE_EXTRA_CA_CERTS="$HOME/certs/company-root.pem" in your shell profile. Node reads the variable only when a process starts, so open a new terminal.

--strict-ssl=false also got npm through the inspecting proxy, by switching off certificate checks for every request to the registry. Use it once to confirm the diagnosis, then set up the certificate.

pnpm and Yarn

pnpm still reads proxy, https-proxy and http-proxy from .npmrc. Its current documentation lists httpsProxy, httpProxy and noProxy as settings for pnpm-workspace.yaml. One change matters for company setups: since pnpm 11.5.3, a proxy address with a placeholder such as ${HTTPS_PROXY} in the project .npmrc at the workspace root "is ignored, and pnpm prints a warning", in the words of its documentation.

Yarn 2 and later read httpProxy, httpsProxy, httpsCaFilePath and enableStrictSsl from .yarnrc.yml. We tested neither pnpm nor Yarn.

npm's proxy is not your code's proxy

Setting npm's proxy changes nothing for the programs npm installs. A Node script that calls fetch or axios opens its own connections and never reads .npmrc. Our Node.js proxy guide covers that side, tested the same way, and the guides to node-fetch and axios go into those two clients. For Git behind the same proxy, see Git proxy settings and errors.

How we tested

On 27 September 2026 we ran three tests on one Windows machine with Node 22.19, using npm 11.8.0 and npm 10.9.3. Each npm run got an empty user and global .npmrc, a new cache and no retries, so nothing from the machine's own setup could interfere.

  • 42 proxy setups. npm asked a registry on our machine, named registry.lab.test, for a package. That name exists nowhere else, so npm could reach the registry only through one of our proxies, and each proxy logged what it received. We ran every setup twice on both versions. All 84 results matched between the runs, and both versions behaved the same.
  • The config commands. 21 npm config commands per version against a throwaway .npmrc, run twice.
  • The silent proxy. npm against a proxy that never answers, with a 10-minute limit, run twice.
  • The real registry. npm view left-pad version against registry.npmjs.org with no proxy, with a company root in cafile, in NODE_EXTRA_CA_CERTS and in both, plus plain http:// requests to the registry, run twice.

The certificate authorities were made for the tests and deleted afterwards.

npm 12 was not run. Version 12.0.0 came out on 8 July 2026, and 12.1.0, the latest, on 22 September. We compared the proxy code inside the published packages: the file that sets up the proxy is byte for byte the same in npm 10.9.3, 11.8.0 and 12.1.0. In 12.1.0 the step that asks the proxy for a tunnel still has no time limit, so the results above should hold there too.

Sources

Frequently asked questions

How do I set a proxy for npm?
Run npm config set https-proxy http://user:pass@proxy.example.com:3128 and the same for proxy. The address starts with http:// even for https-proxy, unless your proxy itself takes encrypted connections. npm uses https-proxy when it is set and proxy otherwise, for every request. In our test on npm 11.8.0 and 10.9.3, HTTP_PROXY in the environment did not cover the https registry; HTTPS_PROXY did.
How do I see which proxy npm uses?
npm config list shows the proxy settings from every .npmrc file, with passwords as ***. npm config get https-proxy prints null when the proxy comes from the HTTPS_PROXY variable, and it refuses to print an address that holds a password. Check the environment as well: Get-ChildItem Env:*proxy* in PowerShell, or env | grep -i proxy on macOS and Linux. Since npm 11.8.0, npm config list also shows proxy variables from the environment.
How do I remove the npm proxy?
Run npm config delete https-proxy and npm config delete proxy; npm config rm does the same. Then remove HTTPS_PROXY from the environment. npm config set proxy false does not remove anything: it writes proxy=false into .npmrc, and in our test a proxy in HTTPS_PROXY stayed in use.
What does npm error code E407 mean?
The proxy wants a login. npm prints npm error code E407 and 407 Proxy Authentication Required with the address it tried to fetch. Put the login into the proxy address, http://user:pass@proxy.example.com:3128, and write special characters in percent form, for example @ as %40 and # as %23.
How do I use a SOCKS5 proxy with npm?
Set https-proxy to a socks5h:// address, for example socks5h://user:pass@proxy.example.com:1080. In our test npm then passed the registry name to the proxy. With socks5:// npm looked the name up on the machine first, and on a network that cannot resolve outside names that fails with ENOTFOUND before the proxy is asked.
How do I fix SELF_SIGNED_CERT_IN_CHAIN or UNABLE_TO_GET_ISSUER_CERT_LOCALLY in npm?
A proxy is opening HTTPS and signing it again with an authority npm does not trust. Get that authority's root certificate as a PEM file and point NODE_EXTRA_CA_CERTS at it; it adds the root to Node's list. npm config set cafile works too, but it replaces npm's whole list, so away from that network npm rejects the normal registry, with UNABLE_TO_GET_ISSUER_CERT_LOCALLY in our test. strict-ssl false only confirms the diagnosis.

Get proxies that are alive right now

Our free proxy list re-checks every exit every few minutes across 100+ countries, with a live last-checked time, so you copy IPs that worked moments ago, not a stale text dump. When the location has to survive a real check, the paid network holds up.

129M+ proxy checks run · 100+ countries · HTTP / HTTPS / SOCKS · re-checked every few minutes · no signup

HProxy.

Honest guides and comparisons on proxies, scraping and staying unblocked, from the team that runs the network.

RSS feed