DNS Troubleshooting

DNS Lookup Failed? What NXDOMAIN, SERVFAIL and EAI_AGAIN Mean

Published 8 min read
Four cards decoding dig status results: NXDOMAIN, NOERROR with no answers, SERVFAIL and a timeout, each with its likely cause

Short answer: "DNS lookup failed" means your device asked a DNS resolver to turn a hostname into an IP address and did not get a usable answer. The wording changes from tool to tool (Could not resolve host in curl, ENOTFOUND in Node.js, Temporary failure in name resolution on Linux), but the cause is almost always one of four things: the name does not exist, the name exists but has no record of the type you asked for, the resolver could not get a valid answer, or your machine cannot reach a resolver at all. The fastest way to tell which one you have is to run one dig command and read the status line.

This guide is a decoder for the messages developers and admins actually see. If your problem is the browser page that says "DNS server isn't responding", read our DNS server not responding guide; for the Chrome-specific NXDOMAIN page see how to fix DNS_PROBE_FINISHED_NXDOMAIN.

Step 1: ask DNS directly and read the status

Error messages from apps are second-hand. Ask DNS yourself, against a public resolver, and compare it with what your own machine uses:

dig example.com A @1.1.1.1
dig example.com A @8.8.8.8
dig example.com A

Look at the status: field in the header of the answer. It is the DNS response code (RCODE) defined in RFC 1035, and it tells you where to look next:

What you seeMeaningWhere to look
status: NXDOMAINThe name does not exist in DNS.Typo, expired domain, record never created, or a stale negative cache.
status: NOERROR with ANSWER: 0The name exists but has no record of that type (often called NODATA).Ask for the right type: A, AAAA, CNAME, MX or TXT.
status: SERVFAILThe resolver tried and failed to get a valid answer.Broken delegation, dead authoritative servers, or DNSSEC validation failure.
status: REFUSEDThe server will not answer you.You are querying a resolver that restricts clients, or a nameserver that is not authoritative for the zone.
connection timed out; no servers could be reachedNo reply at all.Your network, firewall or VPN, or a wrong resolver address.

A useful rule: if the public resolvers return an answer but your default resolver does not, the problem is local (your resolver, router, VPN or /etc/resolv.conf). If every resolver fails the same way, the problem is in the domain's DNS, and no setting on your computer will fix it.

What each common error message means

Where you see itExact messageUsually means
curlcurl: (6) Could not resolve host: example.comAny resolution failure (libcurl error CURLE_COULDNT_RESOLVE_HOST). It does not say whether it was NXDOMAIN, SERVFAIL or a timeout, so run dig.
Node.jsgetaddrinfo ENOTFOUND example.comThe name did not resolve: NXDOMAIN or no address records.
Node.js, Docker, CIgetaddrinfo EAI_AGAIN example.comA temporary failure: the resolver timed out or could not be reached. Retrying may work, and so may fixing the network.
Linux (ping, apt, git)Temporary failure in name resolutionThe same EAI_AGAIN condition from the C library: no working resolver is configured or reachable.
Linux (ssh, wget)Name or service not knownThe same as ENOTFOUND: the resolver answered, and the name is not there.
Pythonsocket.gaierror: [Errno -2] Name or service not known and [Errno -3] Temporary failure in name resolutionThe two cases above, with -2 for "not found" and -3 for "try again" on Linux (glibc).
Windows pingPing request could not find host example.com. Please check the name and try again.Name did not resolve.
Windows nslookupDNS request timed out. timeout was 2 seconds.The configured resolver did not reply.
ChromeERR_NAME_NOT_RESOLVEDResolution failed in the browser. If the page says DNS_PROBE_FINISHED_NXDOMAIN, the name does not exist.

The Linux wording comes from the C library function getaddrinfo, whose documented error codes EAI_NONAME ("name or service not known") and EAI_AGAIN ("temporary failure in name resolution") are explained in the getaddrinfo manual page. Most languages and tools simply print that code, which is why the same fault shows up in so many different outfits.

If it is NXDOMAIN: the name does not exist

Work through these in order, because the first one is the most common:

  1. Typo or wrong environment. A hostname in a config file, .env or Kubernetes manifest that points to api.staging.example.com when only api-staging.example.com exists will fail everywhere.
  2. The record was never created, or was created in the wrong zone. If you changed nameservers recently, the zone your registrar delegates to may not contain the record. Check the delegation with our nameserver lookup and look at the records with the DNS lookup tool; the walkthrough is in how to check a domain's nameservers.
  3. The domain expired or was suspended. Check registration status with the WHOIS lookup.
  4. Negative caching. If you queried a name before creating the record, resolvers may remember "does not exist" for a while. RFC 2308 lets resolvers cache that answer for a period based on the zone's SOA record, so the new record can look missing from some networks for minutes. See DNS propagation explained for how to wait it out safely.

If it is SERVFAIL: the resolver could not get a valid answer

SERVFAIL is the most misunderstood result because it points at a fault upstream of you. The usual causes are authoritative nameservers that do not answer (lame delegation), nameservers listed at the registrar that do not actually host the zone, and DNSSEC validation failures. Try these two commands:

dig example.com A +trace
dig example.com A @1.1.1.1 +cd

+trace walks from the root servers down and shows the step where it breaks. +cd sets "checking disabled", which asks the resolver to skip DNSSEC validation. If the plain query returns SERVFAIL but the +cd query returns an answer, the domain has a DNSSEC problem, typically a DS record at the registrar that no longer matches the zone's keys. Our DNSSEC check guide shows how to confirm the chain.

Modern resolvers can also explain themselves. Extended DNS Errors, defined in RFC 8914, add a code and sometimes text to a failure, and recent versions of dig print it as an EDE line. For example, code 22 is "No Reachable Authority" (the authoritative servers did not respond) and code 6 is "DNSSEC Bogus". If you see an EDE line, it is the quickest clue you will get.

If it is a timeout or EAI_AGAIN: you cannot reach a resolver

When even dig @1.1.1.1 times out, the DNS query never reaches a server or the reply never returns. Check the local path first:

  • Linux with systemd-resolved: resolvectl status shows the servers in use for each interface, and resolvectl query example.com tests resolution through the same path your applications use. Run cat /etc/resolv.conf too: 127.0.0.53 means the local stub is in charge, and an empty or missing nameserver line explains Temporary failure in name resolution immediately.
  • Windows: ipconfig /all lists the DNS servers, and ipconfig /flushdns clears the local cache.
  • macOS: scutil --dns lists resolvers per interface; sudo killall -HUP mDNSResponder clears the cache.
  • Docker and CI runners: inside the container, cat /etc/resolv.conf. On a user-defined Docker network the resolver is Docker's embedded DNS at 127.0.0.11, which forwards to the host's resolvers. A container that works on your laptop and fails in CI often inherits an unreachable corporate or VPN resolver.
  • VPN, firewall or captive portal: some block outbound UDP and TCP port 53, or hand out a private resolver that only answers internal names. Test with dig +tcp example.com @1.1.1.1 to see whether TCP gets through when UDP does not.

To test a specific server instead of the system default, see how to use nslookup with a specific DNS server.

A 60-second triage you can reuse

  1. Run dig yourhost.com A @1.1.1.1 and read status:.
  2. Run the same query without @. If only this one fails, fix your local resolver, VPN or router.
  3. NXDOMAIN on both: fix the name or the zone. NOERROR with no answer: you asked for the wrong record type.
  4. SERVFAIL on both: run +trace and +cd, then check delegation and DNSSEC.
  5. Only after DNS is fixed, flush caches and retry the app. Restarting the app first just hides the evidence.

Intermittent EAI_AGAIN in a build or deploy pipeline is usually a resolver that is slow or overloaded rather than a wrong name. Retrying with a short back-off and pointing the runner at a reliable resolver is a legitimate fix there, but only after you have confirmed with dig that the name itself resolves.

Frequently asked questions

Is DNS lookup failed the same as no internet?

No. You can have a working connection and still get this error if DNS is misconfigured. Run ping 1.1.1.1: if that works but ping example.com does not, your network is fine and name resolution is the problem.

Why does the error come and go?

Usually one of several resolvers or authoritative nameservers is failing. Clients try them in turn, so some requests succeed. Query each authoritative nameserver listed for the domain with dig and compare the answers.

Can switching to 1.1.1.1 or 8.8.8.8 fix a failed lookup?

It fixes problems caused by your ISP or router resolver. It cannot fix a domain whose own DNS is broken, and it can stop internal-only names resolving on a corporate network.

How long should I wait after adding a DNS record?

If nobody queried the name before, it works as soon as the authoritative servers have the record. If a resolver cached that the name does not exist, the wait can be as long as the negative-caching period set by your zone SOA record (RFC 2308).

;; related guides

Related Posts