Error: getaddrinfo ENOTFOUND api.example.com
Node.js · updated 2026-11-02
Thrown when Node asks the operating system's resolver for a hostname and gets no address back, before any connection is attempted. The message ends with the hostname it tried, which is the fastest clue: an empty value, the word undefined, a scheme glued onto the host, or a name that only exists on another network.
Error: getaddrinfo ENOTFOUND payments.internal
at GetAddrInfoReqWrap.onlookupall [as oncomplete] (node:dns:120:26) {
errno: -3008,
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'payments.internal'
}Quick fix
Read the hostname at the end of the message. If it looks wrong (undefined, a full URL, a typo), fix the config or env var that builds it. If it looks right, resolve it from the same machine or container (getent hosts <name> or nslookup <name>): a name that resolves on your laptop but not in production points at internal DNS, a service name from another network, or a container without DNS.
- Copy the hostname from the end of the message and check it for typos, 'undefined' and a leftover scheme or path.
- Find where the URL is built and log the env var behind it in that environment.
- Resolve the name from the failing host or container: getent hosts <name>, or nslookup <name>.
- For Docker or Kubernetes, use the service name on the same network, or the full DNS name for another namespace.
- If it fails only sometimes, look at the resolver: a DNS timeout under load shows up as EAI_AGAIN rather than ENOTFOUND.
// Fail at startup with a clear message instead of on the first request
const base = process.env.PAYMENTS_URL;
if (!base) throw new Error("PAYMENTS_URL is not set");
const url = new URL("/v1/charges", base); // throws on a malformed base URL
// Check resolution from inside the same container
// $ getent hosts payments.internalWhy it happens
The hostname comes from a missing or wrong env var
An unset variable turns into the literal hostname undefined, and a value with a scheme or path passed where only a host is expected (for example to http.request({ host })) becomes an invalid name.
A name that only exists on another network
Internal names (Docker service names, Kubernetes services, VPC-only DNS, /etc/hosts entries on a laptop) do not resolve from a different network, namespace or machine.
Typo in the domain
A misspelled host or a dropped subdomain does not resolve. Because DNS fails before any connection, this looks like a network problem even though it is a config error.
The container has no working DNS
A container on a custom network, a restrictive network policy, or a broken resolv.conf can leave every external name unresolvable.
The domain or record no longer exists
An expired domain, a deleted DNS record or a decommissioned third-party endpoint all produce ENOTFOUND for code that used to work.
Other fixes
- Validate service URLs at startup with new URL() so a bad value fails the deploy, not the first request.
- Retry only EAI_AGAIN (temporary DNS failure); ENOTFOUND for a bad name will not fix itself.
- Add the hostname to error reports so you can tell config mistakes from outages at a glance.
Same error, other wording
- Error: getaddrinfo ENOTFOUND undefined
- Error: getaddrinfo EAI_AGAIN api.example.com
- FetchError: request to https://api.example.com/ failed, reason: getaddrinfo ENOTFOUND api.example.com
Let your coding agent catch the next one
Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:
> Find the getaddrinfo ENOTFOUND errors in production, list the hostnames they failed on and the release behind the latest one, and work out whether each is a config value, an internal name used from the wrong network, or a domain that no longer resolves.
Related errors
References: Node.js: dns.lookup() and getaddrinfo, Node.js: Common system errors