The "proxy authentication required" error (HTTP 407) occurs when npm cannot authenticate with a corporate proxy server. Fixing it means supplying valid proxy credentials to npm, ideally without leaking the password into committed files or shell history.
This error indicates that your network requires traffic to go through an authenticated proxy, and npm hasn't provided valid credentials. Corporate networks often use proxy servers for security, monitoring, and caching purposes. When the proxy returns HTTP 407, it means npm's request was intercepted and credentials are required. Unlike HTTP 401 (which comes from the destination server and means the registry or destination needs auth), 407 specifically means the proxy server in front of you — not the registry — requires authentication. This distinction matters: a 401 is fixed with `npm login`/auth tokens, while a 407 is fixed with proxy configuration.
Point npm at your proxy and include credentials in the URL:
npm config set proxy http://username:[email protected]:8080
npm config set https-proxy http://username:[email protected]:8080URL-encode special characters in the password (@ becomes %40, etc. — see the dedicated step below).
Security warning: npm config set proxy http://user:password@... writes your password in cleartext to ~/.npmrc. That file is routinely committed to dotfiles repos, synced to cloud backups, or copied into Docker images and CI logs — any of which leaks your corporate credentials. Treat this with care:
- Never commit `.npmrc`. Add it to .gitignore (both ~/.npmrc patterns and any project-local .npmrc).
- For automated environments, prefer pulling the value from a secret store (Vault, AWS Secrets Manager, your CI's secret variables) at runtime instead of persisting it on disk.
- Rotate the password if you suspect it was ever committed or logged.
Instead of writing credentials to ~/.npmrc, npm also reads standard proxy environment variables:
export HTTP_PROXY=http://username:[email protected]:8080
export HTTPS_PROXY=http://username:[email protected]:8080
export NO_PROXY=localhost,127.0.0.1,.company.comThis keeps the password out of ~/.npmrc, but it is not inherently more secure: the password is still inline in the URL, so it lands in your shell history (~/.bash_history, ~/.zsh_history) and is visible in the process environment to anything that can read /proc or run ps/env.
To avoid the shell-history leak, source the value from a secret store rather than typing it literally, e.g.:
# password fetched from a secret manager, never typed inline
export PROXY_PW="$(read-from-secret-store proxy-password)"
export HTTPS_PROXY="http://username:${PROXY_PW}@proxy.company.com:8080"Or add a leading space to the export command if your shell is configured with HISTCONTROL=ignorespace. The goal is the same as Step 1: keep the cleartext password out of files and history.
If your password contains characters that are meaningful in a URL, you must URL-encode them or npm will misparse the proxy URL:
# If password is "P@ss#word!"
# @ = %40, # = %23, ! = %21
npm config set proxy http://user:P%40ss%23word%21@proxy:8080Common encodings: @ = %40, # = %23, $ = %24, ! = %21, & = %26, : = %3A, / = %2F, % = %25.
npm cannot perform NTLM or Kerberos authentication itself. Run a local helper proxy that handles Windows auth and forwards to npm over plain HTTP.
cntlm is the classic option:
# Install cntlm
sudo apt install cntlm # Linux
brew install cntlm # macOSDo not put your plaintext domain password in `/etc/cntlm.conf`. Instead, generate a hashed PassNTLMv2 value so the cleartext password never sits in the config file:
# Generates PassLM/PassNT/PassNTLMv2 hashes; you type the password once, interactively
cntlm -H -u your-domain-username -d YOURDOMAINCopy only the PassNTLMv2 line it prints into /etc/cntlm.conf (alongside Username, Domain, and the upstream Proxy entries), and remove any plaintext Password line. Then start cntlm and point npm at it:
sudo cntlm -c /etc/cntlm.conf
npm config set proxy http://localhost:3128
npm config set https-proxy http://localhost:3128px is a good modern alternative (especially on Windows) and can use the logged-in user's Kerberos/NTLM credentials without storing any password.
On corporate networks the proxy often performs TLS interception (MITM), re-signing HTTPS with an internal CA. Once the 407 is resolved, the very next failure you may hit is a certificate error such as:
npm ERR! code SELF_SIGNED_CERT_IN_CHAIN
npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLYThis is not an npm bug — npm just doesn't trust your company's internal CA yet. Do not "fix" it with npm config set strict-ssl false; that disables certificate verification entirely and exposes you to real man-in-the-middle attacks.
Instead, obtain your corporate root CA certificate (PEM format) from your IT team and point npm at it:
npm config set cafile /path/to/corp-ca.pemIf you have multiple CAs, concatenate them into one PEM file. You can also set NODE_EXTRA_CA_CERTS=/path/to/corp-ca.pem so Node itself (and other Node tooling) trusts the CA.
Check your current npm proxy configuration:
npm config get proxy
npm config get https-proxy
npm config listEnsure the values match your corporate proxy host and port. Watch for stale or duplicate settings left over from a previous network.
Confirm the proxy itself works independently of npm:
# Test with curl
curl -x http://user:pass@proxy:8080 https://registry.npmjs.org
# Check npm verbose output
npm install --verbose 2>&1 | grep -i proxyIf curl succeeds but npm fails, the issue is in npm's config rather than the proxy or your credentials.
For NTLM/Kerberos environments, local helper proxies (cntlm, px, or Fiddler) terminate Windows authentication and expose a simple authenticated-or-anonymous local endpoint to npm; prefer hashed credentials (cntlm's PassNTLMv2) or Kerberos ticket reuse (px) over storing a plaintext password.
In CI/CD, source proxy credentials from a secret manager at runtime and never commit them — remember that any inline user:password@ URL can still leak into build logs.
Many enterprises distribute proxy configuration via a PAC file. npm cannot consume PAC files directly; you'll need to read the PAC to determine the concrete proxy host/port (or let a tool like px evaluate it) and configure npm with that resolved value.
If you frequently hit both 407 and TLS-interception (SELF_SIGNED_CERT_IN_CHAIN) issues, consider running an internal npm registry/mirror inside the network perimeter to reduce reliance on the egress proxy entirely.
npm notice access token expired or revoked. Please try logging in again.
Token has expired - npm authentication failure
npm ERR! code EAI_AGAIN
How to fix "EAI_AGAIN" in npm
npm error code E403 npm error 403 Forbidden - PUT https://registry.npmjs.org/<package>
How to fix 'E403 Forbidden' error in npm
npm ERR! code EUSAGE npm ERR! Usage error
How to fix "npm ERR! code EUSAGE" in Node.js projects
npm ERR! code E401 npm ERR! 401 Unauthorized
How to fix "E401 Unauthorized" in npm