npm fails with code EAI_AGAIN when it can't resolve registry.npmjs.org via DNS. It's usually a transient or misconfigured DNS issue you fix by testing resolution and switching DNS servers.
EAI_AGAIN is a DNS resolution error returned by the operating system's `getaddrinfo()` call, meaning "temporary failure in name resolution." When npm connects to the registry (by default `registry.npmjs.org`), it must first resolve that hostname to an IP address. If the configured DNS resolver is unreachable, overloaded, or blocked, `getaddrinfo()` returns EAI_AGAIN and npm aborts. Unlike EAI_NONAME (the host genuinely does not exist), EAI_AGAIN signals a soft/transient failure, so a retry can succeed once connectivity or DNS is restored. In practice it most often appears behind corporate proxies/firewalls, on flaky networks, or inside containers and VMs (Docker, WSL2) where DNS is misconfigured.
Try resolving the exact hostname from the error message:
nslookup registry.npmjs.org
# or
dig registry.npmjs.orgIf resolution fails or times out, DNS is the problem. Also check which registry npm is using, in case it is a private one that your network cannot resolve:
npm config get registryBecause EAI_AGAIN means a *temporary* resolution failure, simply re-running the command after a moment frequently works:
npm installIf you are behind a slow or congested DNS server, increasing npm's network timeout can also help:
npm install --fetch-timeout=60000If it succeeds intermittently, the underlying issue is a flaky resolver or network rather than a hard misconfiguration.
Verify you have connectivity and that DNS specifically is the failing layer:
# Connectivity to a known IP (bypasses DNS)
ping -c 3 1.1.1.1
# Name resolution + HTTPS to the registry
curl -I https://registry.npmjs.orgIf ping 1.1.1.1 works but curl https://registry.npmjs.org fails on name resolution, the problem is DNS. If even ping 1.1.1.1 fails, fix the network/VPN connection first.
A stale cache can keep a failed lookup around. Clear it for your OS:
# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
# Windows
ipconfig /flushdns
# Linux (systemd-resolved)
sudo resolvectl flush-caches # older systemd: sudo systemd-resolve --flush-cachesIf your ISP/corporate resolver is the culprit, point your system at a public resolver such as Cloudflare (1.1.1.1) or Google (8.8.8.8).
Important: do not hand-edit /etc/resolv.conf on most modern Linux systems — it is auto-generated and will be overwritten by NetworkManager, systemd-resolved, or your DHCP client on the next network change or reboot. Configure DNS through the manager that owns it so the change persists:
# NetworkManager (find your connection name with: nmcli connection show)
sudo nmcli connection modify "<connection-name>" ipv4.dns "1.1.1.1 8.8.8.8"
sudo nmcli connection modify "<connection-name>" ipv4.ignore-auto-dns yes
sudo nmcli connection up "<connection-name>"
# systemd-resolved (global): edit /etc/systemd/resolved.conf, set
# DNS=1.1.1.1 8.8.8.8
# then
sudo systemctl restart systemd-resolvedOn macOS: System Settings > Network > your interface > Details > DNS. On Windows: change the DNS servers in the adapter's IPv4 properties (or Set-DnsClientServerAddress in PowerShell). These survive reboots, unlike a manual /etc/resolv.conf edit.
On a corporate network or VPN you may be required to use an internal DNS server and an HTTP proxy. Make sure npm is configured for the proxy:
npm config set proxy http://proxy.example.com:8080
npm config set https-proxy http://proxy.example.com:8080If you previously set a proxy that no longer applies (e.g. after leaving the VPN), clear it:
npm config delete proxy
npm config delete https-proxyConfirm with your network admin that outbound DNS (UDP/TCP 53, or DoH/DoT) and access to the registry host are permitted.
If the error only happens inside Docker or WSL2, the container/VM DNS config is usually the cause.
# Docker: run with explicit resolvers
docker run --dns 1.1.1.1 --dns 8.8.8.8 ...Or set DNS persistently in Docker's /etc/docker/daemon.json:
{
"dns": ["1.1.1.1", "8.8.8.8"]
}then sudo systemctl restart docker. For Kubernetes, check CoreDNS/kube-dns pod health (kubectl get pods -n kube-system). For WSL2, see the Advanced notes below.
WSL2 generates /etc/resolv.conf automatically and will overwrite manual edits unless you disable that behavior. To pin custom DNS, add to /etc/wsl.conf:
[network]
generateResolvConf = falsethen wsl --shutdown from Windows, reopen WSL, and write your own /etc/resolv.conf with nameserver 1.1.1.1.
If you must use a temporary hosts-file workaround, never hardcode a guessed IP — registry.npmjs.org is served by Cloudflare with rotating, geo-distributed addresses, so a stale entry causes more outages than it fixes. Resolve the current IP yourself (dig +short registry.npmjs.org) only if absolutely necessary, and remove the entry as soon as DNS works again; the durable fix is correcting the resolver, not pinning an IP.
EAI_AGAIN can also surface when the registry is reachable but rate-limited or returning errors slowly; if DNS clearly resolves (dig succeeds) yet npm still reports EAI_AGAIN, suspect a proxy/firewall doing DNS interception rather than your resolver itself.
npm notice access token expired or revoked. Please try logging in again.
Token has expired - npm authentication failure
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
npm ERR! DEPTH_ZERO_SELF_SIGNED_CERT
How to fix "DEPTH_ZERO_SELF_SIGNED_CERT" in npm