DNS returns NXDOMAIN for a record that exists -- stale resolver or propagation delay
dig/nslookup returns NXDOMAIN for a domain that was recently updated
Focused incident mode — strips away everything but this runbook.
Symptoms
- dig/nslookup returns NXDOMAIN for a domain that was recently updated
- curl: Could not resolve host, but the record is visible at the authoritative nameserver
- Some resolvers return the record while others do not
Low TTLs (60-300s) are critical when making DNS changes. Pre-lower TTL 24h before the change to minimize propagation windows.
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Local resolver output
dig <domain> +short +statsAuthoritative server output
dig <domain> @<authoritative-ns> +short
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- Authoritative NS returns the record but the local resolver does not
- Record was changed within the last TTL window
Confirm before fixing
dig <domain> @<upstream-resolver> +noall +answerQuery the upstream resolver directly to confirm stale data
Expected: NXDOMAIN or old record
Fix
dig <domain> @<upstream-resolver> +norecurseAsk the resolver to re-query without recursion
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
dig <domain> @<authoritative-ns> +shortVerify the record exists at source
dig <domain> +short +statsCheck what the local resolver returns
dig <domain> @<upstream-resolver> +noall +answer +ttlidCheck the cached TTL on the upstream resolver
dig <domain> @8.8.8.8 +shortCross-check against a public resolver (Google DNS)
Prevention
- Always lower TTL to 60s at least 24 hours before a DNS change.
- Verify the record at the authoritative nameserver, not just a local resolver.
- Use dnsctl or Terraform to manage DNS records and track serial numbers.
- Set up monitoring that queries both authoritative and public resolvers.
Related runbooks
Same stack, same failure family — worth a skim.
dig returns status: SERVFAIL for one or more domains
ping app-server works but ping app-server.internal does not (or vice versa)
curl: Could not resolve host inside pods
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.