In 2023, a fast‑growing SaaS startup lost roughly $250,000 in revenue when a junior engineer removed the A record for payments.api.acme.com and the change propagated as NXDOMAIN across all edge nodes at 02:14 UTC. The incident page logged:
[ERROR] 2023-07-14 02:14:02 - DNS query for payments.api.acme.com returned NXDOMAIN
[ALERT] PagerDuty alert #45892 – Payment gateway unreachable
The team spent three hours hunting logs before discovering the stale negative cache on the recursive resolver. This story illustrates why understanding what NXDOMAIN really means can shave minutes off remediation.
How Does NXDOMAIN Actually Propagate?
A DNS query follows a deterministic path. The client (often dig or a browser) sends a UDP packet to a recursive resolver. The resolver performs iterative queries, asking each authoritative server for the final answer. When the authoritative server has no record for the requested name, it returns a response with the RCODE NXDOMAIN. The resolver then either:
- Caches the negative result for the TTL defined in the SOA (usually 3600 s).
- Forwards the NXDOMAIN to the client.
Negative caching means a correct record restored after a deletion will still be reported as NXDOMAIN until the cached negative entry expires. The client can inspect the RCODE via dig @1.1.1.1 example.com +short or nslookup example.com 1.1.1.1.
Example Terminal Session
$ curl -v https://nxdomain.example.dev
* Trying 192.0.2.1:443...
> GET / HTTP/1.1
> Host: nxdomain.example.dev
>
< HTTP/1.1 200 OK
< Content-Type: text/html
<
* Connection #0 to host nxdomain.example.dev left intact
curl: (6) Could not resolve host nxdomain.example.dev: Name or service not known
The curl error originates from the DNS layer; the host never resolves, so the HTTPS handshake never begins. Developers can add dig nxdomain.example.dev @1.1.1.1 before the request to see the NXDOMAIN directly.
dig Output for NXDOMAIN Diagnosis
$ dig +short example.com @1.1.1.1
; <<>> DiG 1.6.0 <<>> +short example.com @1.1.1.1
;; Question: example.com, type A
;; Answer:
;; Query time: 12 msec
;; Server: 1.1.1.1 in 78.115.206.25
;; WHEN: Tue Jul 16 14:23:45 UTC 2024
;; MSG SIZE rcvd: 45
The final line of the answer section is empty, and the overall RCODE is NXDOMAIN. Seeing an empty answer together with status: NXDOMAIN in a full dig run confirms that the zone truly lacks the name. The AUTHORITY section will list the SOA of the zone, often containing the negative TTL (e.g., ttl=300). Using dig example.com @1.1.1.1 +noall +answer +authority isolates these fields for rapid script parsing.
What Does a Real‑World NXDOMAIN Incident Look Like?
During a client security audit in April 2024, the engineering team observed intermittent payment failures for a European fintech. The error logs consistently showed:
[ERR] 2024-04-12 08:33:15 - DNS resolution for checkout.gateway.fintech.eu failed: NXDOMAIN
The incident spanned 4 hours, affecting roughly 12 k transactions and costing the client an estimated $87 k. The root cause was a misconfigured DNSSEC chain: the RRSIG record for the zone expired, causing the authoritative server to return NXDOMAIN for all subdomains. The DNSSEC key rollover script had not updated the KSK and ZSK before the old keys expired.
Resolution steps:
- Verified the
DNSKEY set on fintech.eu with dig fintech.eu DNSKEY.
- Rotated both
KSK and ZSK using the DNS provider's DNSSEC controls.
- Updated the zone file and re‑published.
- Forced a refresh on recursive resolvers via a 24‑hour TTL flush.
- Confirmed propagation with the free DNS propagation checker on SarangAI.
All services recovered within 12 minutes of the final refresh.
How Can You Systematically Fix NXDOMAIN Issues?
-
Confirm the record is missing
dig @ns1.example.com example.com A returns NXDOMAIN. If it returns NOERROR with no data, the record is NODATA.
-
Check for DNSSEC problems
dig @ns1.example.com example.com DNSSEC displays RRSIG errors. A missing RRSIG or invalid signature indicates a DNSSEC chain issue.
-
Flush negative cache on recursive resolvers
On Linux: sudo systemctl restart systemd-resolved. On Windows: ipconfig /flushdns.
-
Re‑create the missing DNS record
Add an A or AAAA record via your registrar or DNS manager. Ensure the TTL is appropriate (e.g., 300 s for rapid changes).
-
Verify propagation
Use dig example.com @8.8.8.8 from multiple locations. To check a list of hosts, loop over the file: while read h; do dig +short "$h" @8.8.8.8; done < hosts.txt.
-
Monitor with SarangAI's SSL chain checker
After fixing DNS, run openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null to ensure certificates chain correctly, as SSL issues often stem from the same zone misconfiguration.
Each step produces an expected result: the final dig should return a valid IP address, DNSSEC signatures should validate, and the SarangAI SSL checker should report a chain length of ≥2.
Remediation Walkthrough
-
Validate missing A/AAAA record – dig @ns1.example.com example.com A
Expected: status: NXDOMAIN with an empty answer section.
-
Inspect DNSSEC chain – dig @ns1.example.com example.com DNSSEC
Expected: Presence of RRSIG records; otherwise note missing signatures.
-
Clear resolver negative cache – sudo systemd-resolve --flush-caches
Expected: Subsequent dig queries reflect the new record immediately.
-
Re‑add the record – nsedit -a example.com A 192.0.2.1 (or use UI)
Expected: Zone serial increments and the new record appears in the authoritative zone file.
-
Propagate globally – dig example.com @8.8.8.8
Expected: Multiple resolvers return the correct IP for example.com.
-
Confirm DNSSEC validation – dig @ns1.example.com example.com DNSSEC
Expected: All RRSIG records verify successfully.
-
Flush edge CDN cache – aws cloudfront create-invalidation --distribution-id E123 --paths "/*"
Expected: CDN nodes serve the updated DNS resolution within minutes.
-
Run SSL chain verification – openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
Expected: Chain length ≥2 with no validation errors.
Which Common Mistakes Lead to Misdiagnosed NXDOMAIN?
-
Wrong record type – Using dig example.com AAAA when only an A record exists returns NXDOMAIN (or NODATA).
Correct: Query the appropriate record type (dig example.com A).
-
Stale negative cache – After restoring a deleted record, old cached NXDOMAIN persists.
Correct: Flush resolver caches and wait for TTL expiration.
-
DNSSEC key misconfiguration – Expired or mismatched keys cause NXDOMAIN for all subdomains.
Correct: Rotate keys before expiration and publish the new DS record.
-
Typos in the hostname – A single character error changes the queried name.
Correct: Double‑check spelling and use a small dig loop to batch‑verify.
-
Incorrect TTL settings – Very short TTLs can cause temporary NXDOMAIN during propagation.
Correct: Use a TTL of 300–3600 s for production zones.
Quick Reference Table of DNS Failure Codes
| Code | Meaning | Typical TTL Impact | When to Suspect |
|---|
| NXDOMAIN | Non‑existent domain | 0 (authoritative negative cache) | Deleted record, typo, DNSSEC chain break |
| NOERROR | No error, no answer | TTL of SOA (e.g., 3600 s) | Record missing or wrong type |
| NODATA | Name exists, no data of requested type | TTL of SOA | Querying A record when only AAAA exists |
| SERVFAIL | Server failure (backend issue) | N/A | Authoritative server down or internal error |
| YXDOMAIN | Domain exists (for DNS UPDATE) | N/A | Attempting to create an already‑present zone |
| REFUSED | Server refuses to answer | N/A | Access control list or firewall block |
Tools & Commands to Verify NXDOMAIN
- dig:
dig +short example.com @1.1.1.1 – shows RCODE instantly.
- nslookup:
nslookup example.com 1.1.1.1 – older but widely available.
- dig + DNSSEC:
dig +dnssec example.com @1.1.1.1 – shows RCODE, DNSSEC records, and TTL info.
- Python (dnspython):
import dns.resolver
def check_nxdomain(host):
try:
answers = dns.resolver.resolve(host, 'A')
print(f"{host} -> {answers[0]}")
except dns.resolver.NXDOMAIN:
print(f"{host} returned NXDOMAIN")
except dns.resolver.NoAnswer:
print(f"{host} returned NOERROR, no answer")
except Exception as e:
print(f"{host} -> {e}")
check_nxdomain("nxdomain.example.dev")
The script uses the standard dnspython resolver; it catches NXDOMAIN explicitly and prints a human‑readable status.
Key Takeaways
- NXDOMAIN means the queried domain is authoritatively absent, not just unreachable.
- Negative caching can cause false NXDOMAIN for up to the TTL (often 1 hour).
- DNSSEC chain breakage is a common hidden cause; rotate keys before expiration.
- Use the free DNS propagation checker on SarangAI for rapid global verification.
- A short dig loop automates bulk DNS checks, and
+dnssec surfaces DNSSEC validation details.
Frequently Asked Questions
What triggers an NXDOMAIN response?
A missing or deleted DNS record, a typo in the hostname, or a misconfigured DNSSEC chain. The authoritative server signals that the name does not exist in its zone.
How does negative caching affect NXDOMAIN?
Authoritative servers cache negative responses for the TTL defined in the SOA. After a record is restored, stale NXDOMAIN may persist until the cache expires.
Can a recursive resolver return NXDOMAIN incorrectly?
Yes, if the resolver’s cache is stale or the upstream authoritative server misbehaves, leading to false negatives for otherwise valid names.
What tools help pinpoint NXDOMAIN?
dig, nslookup, the free DNS propagation checker on SarangAI, and a dig loop for bulk queries give you visibility into where the failure occurs.
How do you recover from an accidental NXDOMAIN?
Re‑create the missing record, flush resolver caches, and verify propagation with SarangAI's SSL chain checker to ensure the fix is complete.
===MARKER===