getaddrinfo ENOTFOUND (Node, Docker, fetch)
DNS lookup failed before any TCP connection started. The name you asked for does not resolve — often a typo, an empty env var, or a Docker service name that only exists on another network.
What ENOTFOUND means
In Node, Error: getaddrinfo ENOTFOUND some.host is a DNS failure from dns.lookup / getaddrinfo(3). No SYN packet was sent yet — there was no IP to talk to. Axios, undici/fetch, Prisma, Sequelize, Redis clients and http.request all surface the same errno.
Error: getaddrinfo ENOTFOUND db
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:…)
# axios: error.code === 'ENOTFOUND'
# fetch: TypeError: fetch failed → cause.code === 'ENOTFOUND'
Checklist (most common first)
- Empty or wrong env var —
process.env.DB_HOSTisundefined, so the client looks up the literal string"undefined"or falls back to an empty host. Log the resolved URL (redact secrets) before connect. - Typo / wrong TLD —
api.exmaple.com, missing subdomain, or a trailing space from a copied.envline. - Docker Compose service name — From another container, use the service name (
db,redis) on the Compose network.localhostinside a container is that container, not the host or a sibling. From the host machine, use127.0.0.1and the published port. - Private DNS / VPN — Internal names like
api.prod.internalonly resolve on the corporate VPN or in the cluster. Your laptop outside that network gets ENOTFOUND; production does not. - IPv6-only weirdness — Rare, but a name that returns only AAAA while your path is IPv4-only can confuse some stacks. Try the explicit IPv4, or see ECONNREFUSED ::1 when the name does resolve to loopback.
Quick probes
# Does the name resolve at all?
getent hosts db.example.com
# or: dig +short db.example.com
# or: nslookup db.example.com
# Inside the same container/network as the app:
getent hosts db
ping -c1 db # ICMP may be blocked; DNS success still matters
# Print what Node will look up (no secrets):
node -e "console.log(process.env.DATABASE_URL?.replace(/:[^:@/]+@/, ':***@'))"
ENOTFOUND vs ECONNREFUSED vs ETIMEDOUT vs browser NXDOMAIN
| Error | Meaning |
|---|---|
ENOTFOUND | Name → no IP (DNS miss / bad host string) |
ECONNREFUSED | IP reached; nothing accepted the port |
ETIMEDOUT | IP path silent / filtered; see ETIMEDOUT |
Browser ERR_NAME_NOT_RESOLVED | Same DNS miss in Chrome/Edge; see ERR_NAME_NOT_RESOLVED |
Related
DNS_PROBE_FINISHED_NXDOMAIN · TypeError: fetch failed (Node) · ETIMEDOUT / connect ETIMEDOUT · ECONNREFUSED · localhost refused to connect · ERR_NAME_NOT_RESOLVED · TypeError: Failed to fetch · .env files and secrets
Questions
What does getaddrinfo ENOTFOUND mean?
The hostname could not be resolved to an IP address. Fix the name, DNS, or Docker network — not the TCP timeout.
Why ENOTFOUND for localhost?
Usually an empty host string, the literal word undefined from a missing env var, or a typo like localhos. Real localhost should resolve to 127.0.0.1 / ::1.
Why does it work on my laptop but fail in Docker?
Inside Compose, sibling services use service DNS names. localhost points at the container itself. Use the service name and the internal port.
Is ENOTFOUND the same as ETIMEDOUT?
No. ENOTFOUND fails at DNS. ETIMEDOUT means an IP was chosen but the connect/read timed out.
Can a trailing space in .env cause this?
Yes. DB_HOST=db␠ becomes a different label. Quote values and trim when you load them.
How do I debug fast?
Log the hostname you are about to dial (redact passwords), then getent hosts that exact string from the same machine/container as the app.
Published .