getaddrinfo ENOTFOUND means Node.js asked the operating system to turn a hostname into an IP address and got back "no such host". The program never connected to anything. getaddrinfo is the system call that performs the lookup, and ENOTFOUND is Node's code for a failed one.
You see it from http.request, fetch, axios, database clients, npm install, and anything else that connects to a hostname:
Error: getaddrinfo ENOTFOUND api.example.com
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:107:26) {
errno: -3008, code: 'ENOTFOUND', syscall: 'getaddrinfo', hostname: 'api.example.com'
}
Error: getaddrinfo EAI_AGAIN registry.npmjs.org
EAI_AGAIN is the temporary version: the resolver could not be reached or timed out, so it is worth retrying. If the name resolves but the connection is refused, you have a different error; see Node ECONNREFUSED.
Read the hostname in the error
The hostname printed in the error is the exact string Node tried to resolve. A quick look at it solves many cases.
ENOTFOUND undefinedorENOTFOUND null: a variable is missing and the stringundefinedbecame the hostname.ENOTFOUND https://api.example.com: the protocol was included. A hostname must beapi.example.com, withouthttps://.ENOTFOUND api.example.com/v1: a path was included in thehostoption.- A trailing space or newline, often from a
.envfile or a secret manager. ENOTFOUND db: a service name that exists only on a Docker or Kubernetes network.
Causes, most likely first
- Bad hostname string, as above: typo, protocol or path inside it, an empty or untrimmed environment variable.
- The DNS record does not exist, was deleted, or the domain expired or was never delegated.
- DNS not yet propagated after you created the record, or a negative answer cached by a resolver.
- No working DNS in your environment: broken
/etc/resolv.conf, a container with no DNS, a restrictive firewall, or no internet. - Container or cluster naming, where a hostname only resolves inside a particular network.
- A proxy is required but not configured, so direct lookups of external names are blocked.
- Split-horizon or VPN DNS resolving names only when connected.
Step 1: reproduce the lookup outside Node
getent hosts api.example.com # uses the same system resolver as Node's default
dig +short api.example.com
nslookup api.example.com
If dig returns an address but getent does not, the problem is local resolver configuration. If none return anything, the name does not exist in DNS: use the DNS Checker to see whether it resolves anywhere, and the Nameserver Lookup and WHOIS Lookup to check that the domain is registered and delegated. The DNS History tool can show whether a record used to exist.
You can also test inside Node:
require('dns').lookup('api.example.com', (err, addr) => console.log(err?.code, addr));
require('dns').resolve4('api.example.com', (err, addr) => console.log(err?.code, addr));
dns.lookup uses the operating system's getaddrinfo, so it honors /etc/hosts, while dns.resolve4 sends DNS queries directly and ignores the hosts file. Normal HTTP clients use lookup.
Step 2: fix the hostname handling
Parse URLs instead of building them from pieces, and trim input:
const url = new URL(process.env.API_URL.trim()); // throws if invalid or missing
console.log(url.hostname); // api.example.com
https.get({ hostname: url.hostname, path: url.pathname }, cb);
The URL Parser shows how a URL splits into host, port and path. Print the value you pass in, in quotes, to expose stray whitespace: console.log(JSON.stringify(host)).
Step 3: fix DNS in the environment
Linux hosts. Check /etc/resolv.conf and the resolver service:
cat /etc/resolv.conf
resolvectl status
Docker. Containers use Docker's embedded DNS on user-defined networks. Restart containers after DNS changes, and set servers explicitly if needed:
services:
api:
dns:
- 1.1.1.1
- 8.8.8.8
Use the Compose service name for internal hostnames. In Kubernetes, use service.namespace.svc.cluster.local and check CoreDNS pods for failures.
CI and build servers. Network access or DNS may be restricted; allow the hostname through the proxy or allowlist, and for npm check the registry setting with npm config get registry.
Corporate proxies. Configure HTTPS_PROXY, and note that plain Node fetch and http do not use proxy variables automatically in all versions; check your client's proxy support.
Step 4: wait out new or changed records
A record you just created can be absent from some resolvers until caches expire, including negative caching of the earlier "does not exist" answer. See how long DNS propagation takes and DNS explained for website owners. For EAI_AGAIN, retry with backoff.
Step 5: temporary workaround for known hosts
For local development only, an entry in /etc/hosts such as 203.0.113.10 api.example.com makes dns.lookup succeed. Do not use that as a production fix.
How to verify
Run getent hosts HOSTNAME and the dns.lookup snippet and confirm both return an IP address. Then re-run your program and make a real request; confirm an HTTP status with the HTTP Status Checker. Check consistent answers from multiple resolvers with the DNS Checker. Monitor important third-party endpoints with an Uptime Monitor so you notice a changed or dropped DNS record.
Next steps
- Look up the record with the DNS Checker.
- Inspect the domain with the WHOIS Lookup and Nameserver Lookup.
- Read the browser equivalent: ERR_NAME_NOT_RESOLVED and DNS_PROBE_FINISHED_NXDOMAIN.
- Learn about DNS records.
FAQ
What is the difference between ENOTFOUND and EAI_AGAIN?
ENOTFOUND means the resolver answered that the name does not exist. EAI_AGAIN means the lookup failed temporarily, for example the DNS server timed out, so retrying may work.
Why does it work in my browser but not in Node?
The browser may use different DNS settings (DNS over HTTPS, a VPN or a proxy), while Node uses the system resolver. Also check that your code is not putting the protocol or path in the hostname.
Why do I see ENOTFOUND with the hostname "undefined"?
An environment variable or config value was not set when the request was built. Print the value and check that your config loader runs first.
Does ENOTFOUND mean the website is down?
No. It means the name could not be resolved. The site may be fine while your DNS is broken, or the record may really be gone.
Get notified when this fix updates
Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.
This page is general information written by our editorial team and updated when documentation changes. Servers and providers differ, so test changes safely first. See our editorial policy and disclaimer.