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.
Fixes npm ERR! code EAI_AGAIN
nslookup registry.npmjs.org
# or
dig registry.npmjs.orgnslookup registry.npmjs.org# ordig registry.npmjs.orgnpm ERR! code EAI_AGAIN
On this page
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.