The npm registry is unavailable β and the project build has come to a halt. A familiar situation for developers in corporate networks, regions with restricted access, or when working through a strict firewall. In this guide, we will explore all the working methods: from switching to mirrors to fine-tuning the proxy in .npmrc β so that npm install works again without errors.
Why npm registry is blocked and what happens during this
The official npm registry is located at https://registry.npmjs.org. It is a global CDN, but it can still be unavailable for several reasons, each requiring its own approach.
Main reasons for registry unavailability
- Corporate firewall β the company blocks direct requests to external repositories, allowing traffic only through an internal proxy server. This is standard practice in banks, government agencies, and large IT companies.
- Geoblocking or regional restrictions β in several countries and regions, access to npmjs.org is restricted at the level of the internet provider or government firewall.
- Office network without direct internet access β workstations in isolated segments of the network do not have direct access to external resources; all traffic goes through a corporate gateway.
- VPN tunnel with forced proxying β a corporate VPN redirects all traffic, and npm cannot reach the registry directly.
- SSL inspection issues β the corporate proxy intercepts HTTPS traffic and replaces certificates, causing errors like
SELF_SIGNED_CERT_IN_CHAINorUNABLE_TO_VERIFY_LEAF_SIGNATURE.
Typical errors when the registry is blocked
npm ERR! code ECONNREFUSED npm ERR! errno ECONNREFUSED npm ERR! network request to https://registry.npmjs.org/react failed npm ERR! code ETIMEDOUT npm ERR! network This is a problem related to network connectivity. npm ERR! code CERT_HAS_EXPIRED npm ERR! code SELF_SIGNED_CERT_IN_CHAIN
Each of these error codes indicates a different problem: ECONNREFUSED β connection refused by the firewall, ETIMEDOUT β request goes nowhere (blocked without response), certificate errors β SSL inspection issue. Understanding the cause immediately narrows down the range of solutions.
npm registry mirrors: a quick bypass without a proxy
The simplest way to bypass the block is to switch npm to an alternative registry mirror. The mirror contains the same packages as the official registry but is located on different servers and domains. This works when the domain registry.npmjs.org is blocked, not the entire HTTPS traffic.
Popular npm mirrors
| Mirror | URL | Features |
|---|---|---|
| Taobao / npmmirror | https://registry.npmmirror.com |
Synchronization every 10 minutes, good speed from Asia |
| Yarn Berry mirror | https://registry.yarnpkg.com |
Supported by the Yarn team, compatible with npm client |
| Verdaccio (self-hosted) | http://localhost:4873 |
Own registry with caching, works in isolated networks |
| Nexus Repository | http://nexus.company.local/npm |
Corporate solution, proxies and caches packages |
| JFrog Artifactory | https://artifactory.company.com/npm |
Enterprise-level, dependency auditing, access control |
How to switch the registry
Switching for a single command (without changing global settings):
# One-time installation via alternative registry npm install react --registry https://registry.npmmirror.com # Set globally for the current user npm config set registry https://registry.npmmirror.com # Check the current registry npm config get registry # Return to the official registry npm config set registry https://registry.npmjs.org
An important nuance: if you switch to a mirror in a project with a command, it is better to fix this in the .npmrc file at the root of the repository β then all team members will automatically receive the correct configuration when cloning the project.
# .npmrc at the root of the project registry=https://registry.npmmirror.com
Setting up a proxy via .npmrc: complete syntax
When a mirror does not help (for example, when all external HTTPS traffic is blocked), you need to explicitly specify the npm proxy server address. The .npmrc file is the main configuration file for npm, and it is where the proxy settings are stored.
Location of .npmrc files
npm looks for configuration in several places β in order of priority (from highest to lowest):
- Project β
/path/to/project/.npmrcβ applies only to this project - User β
~/.npmrcβ applies for the current user of the system - Global β
$PREFIX/etc/npmrcβ applies for the entire npm installation - Built-in β
/path/to/npm/npmrcβ default settings of npm itself
Proxy configuration syntax in .npmrc
# Proxy for HTTP traffic proxy=http://proxy.example.com:8080 # Proxy for HTTPS traffic (used for most requests to the registry) https-proxy=http://proxy.example.com:8080 # Proxy with authentication (login:password in the URL) proxy=http://username:[email protected]:8080 https-proxy=http://username:[email protected]:8080 # Exceptions β addresses that bypass the proxy noproxy=localhost,127.0.0.1,internal.company.com
β οΈ Important about HTTPS proxy
Note: the https-proxy parameter specifies the address of the proxy server through which npm will make HTTPS requests. The proxy address can start with http:// β this is normal. Most corporate proxies accept connections over HTTP but can tunnel HTTPS through the CONNECT method.
Setting the proxy via npm config commands
An alternative to manually editing the file is to use the npm config set command. It will automatically write the settings to the userβs ~/.npmrc:
# Set proxy npm config set proxy http://proxy.example.com:8080 npm config set https-proxy http://proxy.example.com:8080 # Check current proxy settings npm config get proxy npm config get https-proxy # Remove proxy settings (return to direct connection) npm config delete proxy npm config delete https-proxy # View all npm config npm config list
Proxy via environment variables for npm
npm automatically reads standard system environment variables for proxies. This is convenient in CI/CD pipelines, Docker containers, and systems where configuration is set at the environment level rather than in files.
Standard environment variables
# Linux / macOS β set in the current session export HTTP_PROXY=http://proxy.example.com:8080 export HTTPS_PROXY=http://proxy.example.com:8080 export NO_PROXY=localhost,127.0.0.1 # Lowercase variants (npm understands both) export http_proxy=http://proxy.example.com:8080 export https_proxy=http://proxy.example.com:8080 # Windows (Command Prompt) set HTTP_PROXY=http://proxy.example.com:8080 set HTTPS_PROXY=http://proxy.example.com:8080 # Windows (PowerShell) $env:HTTP_PROXY = "http://proxy.example.com:8080" $env:HTTPS_PROXY = "http://proxy.example.com:8080"
npm configuration priority
It is important to understand that npm uses the following priority when determining the proxy (from highest to lowest):
- Command line flags:
--proxy http://... - Environment variables prefixed with
npm_config_: for example,npm_config_proxy - Project
.npmrc - User
~/.npmrc - Global
$PREFIX/etc/npmrc - Standard environment variables
HTTP_PROXY/HTTPS_PROXY
If the proxy is set in .npmrc, but the environment variable points to a different address β the .npmrc will take precedence. This is a common cause of confusion in CI/CD systems.
Configuration in CI/CD (GitHub Actions, GitLab CI)
# GitHub Actions β add to the env section of the job or step
jobs:
build:
runs-on: ubuntu-latest
env:
HTTP_PROXY: http://proxy.example.com:8080
HTTPS_PROXY: http://proxy.example.com:8080
NO_PROXY: localhost,127.0.0.1
steps:
- uses: actions/checkout@v3
- run: npm install
# GitLab CI β in project variables or in .gitlab-ci.yml
variables:
HTTP_PROXY: "http://proxy.example.com:8080"
HTTPS_PROXY: "http://proxy.example.com:8080"
Corporate proxy with authentication and SSL inspection
Corporate proxy servers are the most complex case. They not only redirect traffic but also require authentication, and often perform SSL inspection (interception and decryption of HTTPS traffic). This leads to specific certificate errors that npm cannot handle out of the box.
Proxy with NTLM/Basic authentication
If the corporate proxy requires a username and password (Basic Auth), they can be passed directly in the URL. However, with NTLM authentication (Windows domain), it is more complicated β npm does not natively support NTLM. In this case, an intermediary tool is used.
# Basic Auth β username and password in the URL npm config set proxy http://user:[email protected]:8080 npm config set https-proxy http://user:[email protected]:8080 # If the password contains special characters β they need to be URL-encoded # @ β %40, # β %23, : β %3A # Example: password "p@ss#word" β "p%40ss%23word" npm config set proxy http://user:p%40ss%[email protected]:8080
For NTLM authentication, the cntlm utility is used β it runs locally, accepts regular HTTP requests, and performs the NTLM handshake with the corporate proxy itself. For npm, this looks like a regular proxy without authentication:
# After configuring cntlm, it listens on localhost:3128 npm config set proxy http://localhost:3128 npm config set https-proxy http://localhost:3128
Solving SSL inspection issues
Corporate proxies with SSL inspection replace the certificates of sites with their corporate certificate. npm checks the trust chain and rejects such certificates. There are three approaches:
Method 1 (recommended): add corporate CA certificate to trusted
# Obtain the corporate certificate from the IT department (file .crt or .pem) # Specify it in the npm configuration npm config set cafile /path/to/corporate-ca.crt # Or add multiple certificates via cafile # You can combine several CAs into one PEM file
Method 2 (temporary, unsafe): disable SSL verification
# Use only as a temporary solution for diagnostics! npm config set strict-ssl false # Or for a single command npm install --legacy-peer-deps --no-strict-ssl
β οΈ Security warning
The parameter strict-ssl false completely disables SSL certificate verification. This makes the connection vulnerable to MITM attacks. Use this method only for diagnostics, not in production or on a permanent basis. The correct solution is to add the corporate CA certificate via cafile.
SOCKS5 proxy for npm: setup via helper utilities
npm natively supports only HTTP/HTTPS proxies. If you have a SOCKS5 proxy (for example, from a provider of residential proxies), it cannot be specified directly in the npm config. An intermediary layer is needed β a utility that accepts HTTP requests from npm and redirects them through SOCKS5.
Method 1: proxychains (Linux/macOS)
# Installing proxychains # Ubuntu/Debian: sudo apt-get install proxychains4 # macOS: brew install proxychains-ng # Configuration /etc/proxychains4.conf [ProxyList] socks5 proxy.example.com 1080 username password # Running npm through proxychains proxychains4 npm install
Method 2: local HTTP-to-SOCKS5 converter
The privoxy or polipo utility creates a local HTTP proxy that tunnels traffic through SOCKS5. After starting, npm sees a regular HTTP proxy at localhost:
# Installing privoxy sudo apt-get install privoxy # Ubuntu/Debian brew install privoxy # macOS # Add to config /etc/privoxy/config: forward-socks5 / proxy.example.com:1080 . # Privoxy listens on localhost:8118 by default # Specify npm to use this address: npm config set proxy http://localhost:8118 npm config set https-proxy http://localhost:8118
Method 3: SSH tunnel as SOCKS5 proxy
If you have access to a remote server with open internet, you can create an SSH SOCKS5 tunnel and route npm traffic through it. This is especially convenient when working from a corporate network with restricted access:
# Create an SSH SOCKS5 tunnel on local port 1080 ssh -D 1080 -f -C -q -N [email protected] # Then use privoxy or proxychains to convert to HTTP # Or directly through the environment variable (Node.js understands SOCKS through some libraries) # Alternative β use curl as a test: curl --socks5 localhost:1080 https://registry.npmjs.org/react/latest
Own private registry as an alternative to a proxy
In corporate and isolated environments, often the best solution is not to set up a proxy for each developer, but to deploy your own npm registry inside the network. Such a registry caches packages from the public npmjs.org and serves them from the internal network. Developers do not need internet access β everything works through the local registry.
Verdaccio: quick start in 10 minutes
Verdaccio is an open-source npm registry with support for proxying and caching. It is installed as an npm package and runs as a separate service:
# Install Verdaccio globally npm install -g verdaccio # Start (by default listens on http://localhost:4873) verdaccio # Configure npm to use the local registry npm config set registry http://localhost:4873 # Publish packages to the local registry npm adduser --registry http://localhost:4873 npm publish --registry http://localhost:4873
The Verdaccio configuration (~/.config/verdaccio/config.yaml) allows you to set up proxying through an external proxy to download packages from npmjs.org:
# config.yaml β uplink configuration with proxy
uplinks:
npmjs:
url: https://registry.npmjs.org/
# If Verdaccio itself is behind a proxy:
agent_options:
http_proxy: http://proxy.company.com:8080
https_proxy: http://proxy.company.com:8080
no_proxy: localhost,127.0.0.1
packages:
'@*/*':
access: $all
publish: $authenticated
proxy: npmjs
'**':
access: $all
publish: $authenticated
proxy: npmjs
Comparison of solutions for isolated environments
| Solution | Complexity | Caching | Suitable for |
|---|---|---|---|
| Mirror (npmmirror) | Low | No | Geoblocking, slow access to npmjs.org |
| HTTP proxy in .npmrc | Low | No | Corporate network with HTTP proxy |
| SOCKS5 + proxychains | Medium | No | Residential/mobile proxies, VPN |
| Verdaccio | Medium | Yes | Teams, isolated networks, CI/CD |
| Nexus / Artifactory | High | Yes | Enterprise, dependency auditing |
Diagnosing and troubleshooting common errors
Even after correctly setting up the proxy, issues may arise. Here is a systematic approach to diagnosis and a list of the most common errors with their solutions.
Step 1: Check the current npm configuration
# Show all npm settings (including proxy) npm config list # Show only proxy settings npm config get proxy npm config get https-proxy npm config get registry npm config get strict-ssl # Enable verbose output for diagnostics npm install react --verbose npm install react --loglevel verbose
Step 2: Check registry availability directly
# Check registry availability via curl curl -v https://registry.npmjs.org/react/latest # Check through the proxy curl -v --proxy http://proxy.example.com:8080 https://registry.npmjs.org/react/latest # Check ping (not always informative for HTTPS) ping registry.npmjs.org # Check DNS resolution nslookup registry.npmjs.org
Typical errors and their solutions
| Error | Cause | Solution |
|---|---|---|
| ECONNREFUSED | Proxy does not accept connections or incorrect port | Check the address and port of the proxy, availability of the proxy server |
| ETIMEDOUT | Request is blocked by the firewall without response | Configure the proxy or switch to a mirror |
| SELF_SIGNED_CERT | SSL inspection by corporate proxy | Add corporate CA via cafile |
| 407 Proxy Auth | Proxy requires authentication | Add username:password in the proxy URL |
| ENOTFOUND | DNS does not resolve the registry or proxy name | Check DNS settings, use IP instead of name |
| E403 Forbidden | Proxy blocks requests to npmjs.org | Use a mirror or contact the network administrator |
Reset all proxy settings
# Remove all proxy settings from the user config npm config delete proxy npm config delete https-proxy npm config delete noproxy # Reset registry to official npm config set registry https://registry.npmjs.org # Restore strict-ssl (if disabled) npm config set strict-ssl true # Check the final config npm config list
Working with pnpm and Yarn when the registry is blocked
If you are using alternative package managers, setting up the proxy looks similar, but the syntax differs slightly:
# pnpm β uses the same .npmrc as npm # Additionally, you can configure via pnpm config: pnpm config set proxy http://proxy.example.com:8080 pnpm config set https-proxy http://proxy.example.com:8080 pnpm config set registry https://registry.npmmirror.com # Yarn Classic (v1) β its own .yarnrc file yarn config set proxy http://proxy.example.com:8080 yarn config set https-proxy http://proxy.example.com:8080 yarn config set registry https://registry.npmmirror.com # Yarn Berry (v2+) β .yarnrc.yml file # httpProxy: "http://proxy.example.com:8080" # httpsProxy: "http://proxy.example.com:8080" # npmRegistryServer: "https://registry.npmmirror.com"
Configuring proxy for specific scoped packages
Sometimes you need to use different registries for different packages: for example, public packages from the official npmjs.org, and corporate @company/* from the internal Nexus. This is configured through scope-specific registry in .npmrc:
# .npmrc β different registries for different scopes registry=https://registry.npmjs.org # Corporate packages @company through internal Nexus @company:registry=http://nexus.company.local/repository/npm-hosted/ # Packages @myorg through Verdaccio @myorg:registry=http://localhost:4873/ # Authentication for specific registry //nexus.company.local/repository/npm-hosted/:_authToken=YOUR_TOKEN_HERE
Conclusion and final recommendations
In conclusion, setting up a proxy for npm when the registry is blocked can be achieved through various methods, including using mirrors, configuring .npmrc, and setting up a private registry. Each method has its own advantages and is suitable for different environments. It is essential to choose the right approach based on your specific needs and infrastructure.
```