ERR_NAME_NOT_RESOLVED / ENOTFOUND (tested)

net::ERR_NAME_NOT_RESOLVED (Chrome), getaddrinfo ENOTFOUND (Node.js), curl: (6) Could not resolve host and Python's gaierror all mean the same thing: DNS gave no IP address for the hostname. No connection was ever tried. We fed the same bad hostnames to four clients and wrote down exactly what each one reports.

1. What the error means

Before a client can connect, it turns the hostname into an IP address. If that step returns nothing, the request stops there. The server never sees it, so server logs, CORS settings and firewall rules are not involved.

There are two DNS answers that lead here. NXDOMAIN: the name does not exist. NODATA: the name exists but has no A or AAAA record (for example only a TXT record). Every client we tested reports both the same way, except Python, which tells them apart.

Compare ERR_CONNECTION_REFUSED / ECONNREFUSED: there the name resolved and the IP answered, but nothing was listening on the port.

2. Exact errors per client

Hostname nonexistent-xyz.invalid. dig returned status: NXDOMAIN. Every client failed in under 50 ms because the answer was immediate.

ClientWhat you see
Chromium page navigationnet::ERR_NAME_NOT_RESOLVED; the tab shows chrome-error://chromewebdata/
Chromium fetch()TypeError: Failed to fetch; console: "Failed to load resource: net::ERR_NAME_NOT_RESOLVED"
Chromium XHR / <img>XHR onerror with status=0, readyState=4; image fires a plain error event
Node.js 24 fetch()TypeError: fetch failed, err.cause.code = ENOTFOUND, cause.syscall = getaddrinfo, cause.hostname = the host
Node.js dns.lookup()getaddrinfo ENOTFOUND nonexistent-xyz.invalid, errno -3008
Node.js dns.resolve4()queryA ENOTFOUND nonexistent-xyz.invalid
curlcurl: (6) Could not resolve host: nonexistent-xyz.invalid, exit 6, %{http_code} = 000
Python socket.getaddrinfosocket.gaierror: [Errno -2] Name or service not known (EAI_NONAME)
Python urllibURLError(gaierror(-2, 'Name or service not known'))
Python requestsConnectionError ... NameResolutionError ... Failed to resolve 'nonexistent-xyz.invalid' ([Errno -2] Name or service not known)

In the browser, JavaScript only gets TypeError: Failed to fetch. The DNS detail is only in DevTools. That same message also covers CORS and refused connections; see TypeError: Failed to fetch for how to tell them apart.

$ curl -sS http://nonexistent-xyz.invalid/
curl: (6) Could not resolve host: nonexistent-xyz.invalid
$ echo $?
6

3. Edge cases we tested

HostnameDNSChromiumNode.jscurlPython getaddrinfo
gooogle-typo-xyz123.com (typo)NXDOMAINERR_NAME_NOT_RESOLVEDENOTFOUNDexit 6-2 Name or service not known
_dmarc.google.com (TXT only, no A/AAAA)NOERROR, no addressERR_NAME_NOT_RESOLVEDENOTFOUND (errno -3007); resolve4: ENODATAexit 6-5 No address associated with hostname
ipv6.google.com (AAAA only)AAAA only200200200OK (IPv6)
example.com. (trailing dot)OK200OK200OK
my_host.invalid (underscore)NXDOMAINERR_NAME_NOT_RESOLVEDENOTFOUNDexit 6-2
bad host.com (space)-sent as bad%20host.com, ERR_NAME_NOT_RESOLVEDfetch: "Failed to parse URL", cause ERR_INVALID_URLexit 3 "URL rejected: Malformed input to a URL function"-2
64-character label + .com-ERR_NAME_NOT_RESOLVEDENOTFOUNDexit 6UnicodeEncodeError ... label too long
bücher.de (IDN)OK as xn--bcher-kva.deconverted to punycode, loadedOKconverted to punycode, loadedOK

What this shows:

4. ENOTFOUND vs EAI_AGAIN vs ESERVFAIL

ENOTFOUND means the resolver gave a definite answer: no address. A broken or unreachable resolver is different. We pointed a Node dns.Resolver at two fake DNS servers on 127.0.0.1 (system settings untouched):

For dns.lookup(), fetch() and most HTTP clients (they use getaddrinfo), a temporary resolver failure shows up as getaddrinfo EAI_AGAIN host (per the Node.js and glibc docs, not measured; we did not break the system resolver). EAI_AGAIN is worth a retry. ENOTFOUND usually is not: fix the name or the record.

5. How to fix it

  1. Copy the exact hostname from the error and check it with dig. NXDOMAIN means the name does not exist. NOERROR with no answer means a record is missing.
    $ dig +short nonexistent-xyz.invalid A        # empty
    $ dig nonexistent-xyz.invalid A | grep status
    ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN
    $ nslookup nonexistent-xyz.invalid
    ** server can't find nonexistent-xyz.invalid: NXDOMAIN
    $ dig +short _dmarc.google.com A               # empty, but TXT exists
    $ dig +short _dmarc.google.com TXT
    "v=DMARC1; p=reject; ..."
  2. Check environment variables and config. An unset variable becomes the literal host undefined. We measured fetch(`http://${process.env.API_HOST}/`) with the variable unset: getaddrinfo ENOTFOUND undefined. A Docker service name used outside its compose network gives the same thing: getaddrinfo ENOTFOUND db.
  3. Check for a proxy. If the proxy hostname is wrong, curl says curl: (5) Could not resolve proxy: myproxy-typo.invalid (exit 5, not 6). Check HTTP_PROXY / HTTPS_PROXY.
  4. New domain or changed record? Resolvers cache answers, including negative ones, for the TTL. Query the authoritative server directly: dig @ns1.yourdns.com name A. If it answers there but not via your resolver, wait for the TTL.
  5. Browser cache. Chrome keeps its own host cache. Per Chrome's docs (not measured), chrome://net-internals/#dns has a "Clear host cache" button.
  6. Test without DNS to prove the server is fine. curl: --resolve host:port:ip. Chromium: --host-resolver-rules. We mapped nonexistent-xyz.invalid to a local server on 127.0.0.1:8983 this way and got 200, with Host: nonexistent-xyz.invalid sent as usual.
    curl --resolve nonexistent-xyz.invalid:8983:127.0.0.1 http://nonexistent-xyz.invalid:8983/
    chromium --host-resolver-rules="MAP nonexistent-xyz.invalid 127.0.0.1:8983"

Once the name resolves, the next errors are usually about the connection: ECONNREFUSED or ECONNRESET.

Frequently asked questions

Is ERR_NAME_NOT_RESOLVED a server problem?

No. The request never left the client. DNS gave no IP address for the hostname, so the server was never contacted. Check the hostname and its DNS records.

What is the difference between ENOTFOUND and EAI_AGAIN?

ENOTFOUND: the resolver answered that there is no address for the name. EAI_AGAIN: the resolver itself failed or timed out (per the Node.js docs). Retry EAI_AGAIN; fix the name or record for ENOTFOUND.

Why does fetch only say 'Failed to fetch'?

Browsers hide network details from JavaScript. In Chromium 153 a DNS failure gave TypeError: Failed to fetch, and the real cause, net::ERR_NAME_NOT_RESOLVED, was only in the console and DevTools.

My domain has a record but I still get ENOTFOUND. Why?

Check the record type. We tested a name with only a TXT record: Chromium, Node.js fetch and curl all failed as if it did not exist. Browsers and HTTP clients need an A or AAAA record.

Does curl exit code 6 always mean DNS?

Yes, exit 6 is 'Could not resolve host'. Exit 5 is the same failure for the proxy host. Exit 3 means the URL itself was rejected, as we saw with a space in the hostname.

Written with AI assistance. Measured on 2026-10-02 with headless Chromium 153.0.8010.12 (Playwright), Node.js 24.21.0, curl 8.14.1, Python 3.13.5 (requests 2.32.3) and dig 9.20 on Debian 13, using the box's normal resolver. No system DNS settings were changed. EAI_AGAIN from getaddrinfo is from the Node.js and glibc docs, not measured. PlainHeaders is our extension; dig, curl, Python, Node.js and Chromium are free.