When anything looks up a hostname that does not exist yet, the resolver it asked remembers the “no such name” answer. Create the record a minute later and that resolver keeps returning NXDOMAIN until the remembered answer expires. The expiry comes from your zone’s SOA record, not from the record you just added, and on a default Cloudflare zone it is 30 minutes.

What an NXDOMAIN answer carries

Random names directly under and.guide don’t produce NXDOMAIN, because our zone has a wildcard (more on that below). For this test we used a random label under www.and.guide, which exists as its own name and has no wildcard beneath it.

Live capture, 26 September 2026. Querying Cloudflare’s resolver (1.1.1.1) and Google Public DNS (8.8.8.8) for a name that had never existed:

dig @1.1.1.1 andguide-neg-kulx7dx5.www.and.guide A
dig @8.8.8.8 andguide-neg-kulx7dx5.www.and.guide A
; <<>> DiG 9.10.6 <<>> @1.1.1.1 andguide-neg-kulx7dx5.www.and.guide A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 43531
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;andguide-neg-kulx7dx5.www.and.guide. IN	A

;; AUTHORITY SECTION:
and.guide.		1800	IN	SOA	frida.ns.cloudflare.com. dns.cloudflare.com. 2414193944 10000 2400 604800 1800

;; Query time: 10 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Sat Sep 26 23:37:49 KST 2026
;; MSG SIZE  rcvd: 127

; <<>> DiG 9.10.6 <<>> @8.8.8.8 andguide-neg-kulx7dx5.www.and.guide A
...
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 37663
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
and.guide.		1800	IN	SOA	frida.ns.cloudflare.com. dns.cloudflare.com. 2414193944 10000 2400 604800 1800

;; Query time: 54 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sat Sep 26 23:37:49 KST 2026
;; MSG SIZE  rcvd: 127

What to read in that output:

  • status: NXDOMAIN says the name does not exist for any record type, not just A.
  • ANSWER: 0, AUTHORITY: 1: the only record returned is the zone’s SOA. RFC 2308 requires authoritative servers to include it precisely so that resolvers can cache the negative answer.
  • The SOA’s last number, 1800, is the MINIMUM field. The TTL column is also 1800. A resolver may keep this NXDOMAIN for the lower of the two: 1,800 seconds, or 30 minutes, counted from the moment it received the answer.
  • There is no ad flag, because and.guide is not DNSSEC-signed.

Both resolvers returned identical answers in the same second, which is what you expect for a name nobody had asked about: each fetched a fresh answer from Cloudflare’s authoritative servers.

How the negative TTL is set

RFC 2308 retired the old meanings of the SOA MINIMUM field and left one: the TTL for negative answers. An authoritative server is supposed to put the lower of MINIMUM and the SOA’s own TTL into the SOA it attaches to a negative answer, and resolvers count that down like any cached record. The RFC calls one to three hours a sensible default and values over a day problematic.

To see your own values without a cache in the way, ask one of the zone’s authoritative servers directly:

dig +short NS and.guide
dig @frida.ns.cloudflare.com and.guide SOA +norec +noall +answer

The and.guide result is the first line of the provider comparison further down.

Not every server applies MINIMUM for you

Live capture, 26 September 2026. Asking a Route 53 name server for a record type slack.com does not publish (a NODATA answer), then asking three resolvers the same question:

dig @ns-1493.awsdns-58.org slack.com NAPTR +norec +noall +comments +authority
for r in 1.1.1.1 8.8.8.8 210.220.163.82; do
  dig @$r slack.com NAPTR +noall +authority +nocmd | grep SOA | sed "s/^/@$r  /"
done
; <<>> DiG 9.10.6 <<>> @ns-1493.awsdns-58.org slack.com NAPTR +norec +noall +comments +authority
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63068
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
slack.com.		900	IN	SOA	ns-1493.awsdns-58.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 300

@1.1.1.1  slack.com.		900	IN	SOA	ns-1493.awsdns-58.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 300
@8.8.8.8  slack.com.		900	IN	SOA	ns-1493.awsdns-58.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 300
@210.220.163.82  slack.com.		300	IN	SOA	ns-1493.awsdns-58.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 300

Route 53 sent the SOA with its full 900-second TTL even though MINIMUM is 300. Our ISP’s default resolver (210.220.163.82) displayed 300; 1.1.1.1 and 8.8.8.8 passed 900 through.

To see what the public resolvers actually do with that, we asked all three about a random NAPTR name under slack.com (also a NODATA) three times a minute for eight minutes and logged status/TTL for each reply (times in KST):

23:43:43 1.1.1.1         NOERROR/900 NOERROR/900 NOERROR/900
23:43:43 8.8.8.8         NOERROR/900 NOERROR/900 NOERROR/900
23:43:43 210.220.163.82  NOERROR/300 NOERROR/300 NOERROR/300
...
23:47:44 8.8.8.8         NOERROR/719 NOERROR/900 NOERROR/659
...
23:49:45 1.1.1.1         NOERROR/599 NOERROR/900 NOERROR/780
...
23:50:45 8.8.8.8         NOERROR/900 NOERROR/659 NOERROR/900

The oldest cached copy either public resolver returned was 301 seconds old (1.1.1.1 showing 599); nothing came back older than that during the whole run. Both appear to expire the answer on the 300-second rule while displaying 900. The practical lesson: read both numbers on the SOA line, and treat the smaller one as your negative TTL.

NXDOMAIN and NODATA are cached differently

Live capture, 26 September 2026. The same record type (TXT) for a name that exists and for one that does not:

dig @1.1.1.1 www.and.guide TXT
dig @1.1.1.1 andguide-neg-yfofkkk4.www.and.guide TXT
; <<>> DiG 9.10.6 <<>> @1.1.1.1 www.and.guide TXT
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34451
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
and.guide.		1800	IN	SOA	frida.ns.cloudflare.com. dns.cloudflare.com. 2414193944 10000 2400 604800 1800
...

; <<>> DiG 9.10.6 <<>> @1.1.1.1 andguide-neg-yfofkkk4.www.and.guide TXT
...
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 2092
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
and.guide.		1800	IN	SOA	frida.ns.cloudflare.com. dns.cloudflare.com. 2414193944 10000 2400 604800 1800
...

The first is NODATA: NOERROR, zero answers, SOA in the authority section. www.and.guide exists (it has A and AAAA records) but has no TXT record. The second is a true NXDOMAIN. They look almost the same, but RFC 2308 caches them under different keys:

Answer What it means Cached per What stays stuck after you add the record
NXDOMAIN The name does not exist Name (all types) Every lookup of that name
NODATA (NOERROR, empty answer) The name exists, but not with this type Name and type Only that record type

Adding a TXT record to an existing name is therefore delayed only for TXT lookups, while a brand-new hostname is blocked for every type until its NXDOMAIN expires.

RFC 8020 adds a reason to build names from the top down: a resolver that has cached NXDOMAIN for a name may treat everything beneath it as nonexistent too. If someone looked up staging.example.com before it existed, a new api.staging.example.com can stay invisible to that resolver until the cached NXDOMAIN for staging.example.com runs out.

DNSSEC-signed zones can look different again. Public resolvers answered a nonexistent name in the signed cloudflare.com zone with NOERROR and an empty answer instead of NXDOMAIN; the DNSSEC guide shows that capture. For signed zones, look for an empty answer plus an SOA rather than for the word NXDOMAIN.

What DNS providers actually publish

Live capture, 26 September 2026. SOA records fetched from one authoritative server of each zone with dig @<server> <zone> SOA +norec +noall +answer. The provider is identified from each zone’s NS records:

and.guide.		1800	IN	SOA	frida.ns.cloudflare.com. dns.cloudflare.com. 2414193944 10000 2400 604800 1800
cloudflare.com.		300	IN	SOA	ns3.cloudflare.com. dns.cloudflare.com. 2415557203 10000 2400 604800 300
porkbun.com.		900	IN	SOA	ns-199.awsdns-24.com. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400
slack.com.		900	IN	SOA	ns-1493.awsdns-58.org. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 300
kubernetes.io.		21600	IN	SOA	ns-cloud-a1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 259200 300
microsoft.com.		3600	IN	SOA	ns1-39.azure-dns.com. azuredns-hostmaster.microsoft.com. 1 3600 300 2419200 300
ns1.com.		3600	IN	SOA	dns1.p01.nsone.net. hostmaster.nsone.net. 1764882848 43200 7200 1209600 3600
netlify.com.		3600	IN	SOA	dns1.p04.nsone.net. hostmaster.nsone.net. 1664458603 43200 7200 1209600 300
nextjs.org.		3600	IN	SOA	ns1.vercel-dns.com. hostmaster.nsone.net. 1655261024 43200 7200 1209600 600
vercel.com.		3600	IN	SOA	ns1.vercel-dns.com. hostmaster.nsone.net. 1657718860 43200 7200 1209600 14400

We also asked each server for a record type the apex does not have (NAPTR) and noted the TTL on the SOA it sent back:

Zone DNS host (from NS) SOA TTL MINIMUM Negative TTL SOA TTL in the negative answer
and.guide Cloudflare 1800 1800 30 min 1800
cloudflare.com Cloudflare (its own name servers) 300 300 5 min 300
porkbun.com Amazon Route 53 900 86400 15 min 900
slack.com Amazon Route 53 900 300 5 min 900
kubernetes.io Google Cloud DNS 21600 300 5 min 300
microsoft.com Azure DNS 3600 300 5 min 300
ns1.com NS1 3600 3600 1 h 3600
netlify.com Netlify (nsone.net and netlifydns.com name servers) 3600 300 5 min 300
nextjs.org Vercel DNS 3600 600 10 min 600
vercel.com Vercel DNS 3600 14400 1 h 3600

How that lines up with each provider’s documented defaults:

  • Cloudflare documents a default MINIMUM of 1800 and returns the SOA with the smaller of its record TTL and MINIMUM. Only Enterprise accounts can change SOA values, so and.guide shows the default and cloudflare.com’s 300 is a customized value.
  • Route 53 documents a default SOA of 1 7200 900 1209600 86400 with a 900-second TTL, so the default negative TTL is 15 minutes. You can edit both numbers. Of eleven Route 53 zones we checked, five still had MINIMUM 86400; the others used 60, 120, 300 (two zones), 1800 and 3600. All eleven had an SOA TTL of 900, and in the seven whose negative answers we checked, Route 53 put 900 on the SOA whatever the MINIMUM said.
  • Google Cloud DNS shows an SOA of 1 21600 3600 259200 300 with a 21600-second TTL in its zone-export example. kubernetes.io matches it exactly, and the server lowered the SOA’s TTL to 300 in its negative answer.
  • NS1 documents a default SOA TTL of 3600 and a default “NX TTL” of 3600, which ns1.com matches. The netlify.com, nextjs.org and vercel.com SOAs carry the same contact (hostmaster.nsone.net) and NS1’s default refresh, retry and expire values, but their MINIMUM values differ: 300, 600 and 14400. Two other Vercel DNS zones we checked, v0.dev and dub.co, also used 600.

Across this sample the negative TTL ranged from 5 minutes to 1 hour. The documented defaults alone differ by a factor of twelve: 300 seconds on Google Cloud DNS, 900 on Route 53, 1800 on Cloudflare and 3600 on NS1.

One resolver address, many caches

Live capture, 26 September 2026. Eight quick queries to each resolver for a nonexistent name we had first looked up about 97 seconds earlier. Each number is the SOA TTL on one reply:

for r in 1.1.1.1 8.8.8.8 210.220.163.82; do
  printf "%-15s" $r
  for i in 1 2 3 4 5 6 7 8; do
    dig @$r andguide-neg-wj5qgh0y.www.and.guide A +noall +authority +nocmd \
      | awk '$4=="SOA"{printf " %s", $2}'
  done
  echo
done
1.1.1.1         1787 1764 1800 1786 1800 1786 1786 1786
8.8.8.8         1724 1703 1800 1702 1702 1702 1800 1785
210.220.163.82  1800 1787 1787 1800 1800 1800 1800 1800

A reply of 1800 came from a cache that had never seen the name and fetched it fresh. 1702 came from a cache that stored it 98 seconds earlier, when we made our first lookup. Large resolvers run many independent caches behind one address, so after you create the record, some caches serve the new answer while others still hold the NXDOMAIN, and repeated tests flip between them. The worst case is still bounded: the negative TTL, counted from the earliest lookup.

A wildcard hides NXDOMAIN, and our zone has one

Live capture, 26 September 2026. A random name directly under and.guide, asked for A and then AAAA at 8.8.8.8:

dig @8.8.8.8 andguide-neg-ggy1bw9x.and.guide A +noall +comments +answer +authority
dig @8.8.8.8 andguide-neg-ggy1bw9x.and.guide AAAA +noall +comments +answer +authority
; <<>> DiG 9.10.6 <<>> @8.8.8.8 andguide-neg-ggy1bw9x.and.guide A +noall +comments +answer +authority
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34330
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
...
;; ANSWER SECTION:
andguide-neg-ggy1bw9x.and.guide. 300 IN	A	115.68.101.36

; <<>> DiG 9.10.6 <<>> @8.8.8.8 andguide-neg-ggy1bw9x.and.guide AAAA +noall +comments +answer +authority
...
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53533
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
...
;; AUTHORITY SECTION:
and.guide.		1800	IN	SOA	frida.ns.cloudflare.com. dns.cloudflare.com. 2414193944 10000 2400 604800 1800

and.guide publishes a wildcard A record (*.and.guide, TTL 300), so any name under and.guide that doesn’t sit beneath another existing name exists as far as DNS is concerned: A lookups get the wildcard’s address and AAAA lookups get NODATA. That has three consequences:

  • Typos never fail at DNS. A mistyped hostname in the zone resolves and then fails at TLS or HTTP, which is harder to diagnose than a clean NXDOMAIN.
  • Positive caching replaces negative caching. If someone resolves a name before you create its explicit record, their resolver keeps the wildcard’s address for up to the wildcard’s TTL (300 seconds here).
  • The wildcard stops at existing names. Under RFC 4592, *.and.guide cannot answer for names beneath www.and.guide, because www.and.guide exists. That is why our NXDOMAIN tests above live under www.

The wildcard subdomains guide covers when a wildcard is worth that trade.

Launch a new hostname without planting NXDOMAIN

  1. Create the record first, then test. Until it exists, check it only against the authoritative server, for example dig @<one-of-your-NS-hosts> app.example.com A +norec. That query goes straight to the source and leaves nothing in any recursive resolver’s cache.
  2. Keep lookups away from the name until then. Browser tabs, uptime monitors, domain-verification checks in hosting dashboards and ACME clients all resolve names, and any of them can plant an NXDOMAIN at a shared resolver.
  3. Create parent names before children if the parent might already have been looked up, because of the RFC 8020 behavior described above.
  4. Plan timed changes. The TTL planner lays out a dated timeline. If your provider lets you edit the SOA (Route 53, NS1’s NX TTL, Cloudflare on Enterprise), lowering it ahead of a launch shortens future negative answers. Answers already cached keep the TTL they were given.

If a resolver already cached the NXDOMAIN

  1. Ask the authoritative server. If it still says NXDOMAIN, the record is not published where you think it is (wrong zone, typo in the name, change not saved), and waiting will not help.
  2. Compare public resolvers. The DNS lookup tool shows Cloudflare’s and Google’s answers side by side with their TTLs.
  3. Work out the deadline. It is the negative TTL counted from the first lookup that cached the answer, not from when you created the record.
  4. Flush what you can. Google Public DNS has a Flush Cache page and 1.1.1.1 has a Purge Cache page; both work per name and record type, so flush the type you are waiting for. Google’s FAQ describes its tool as covering common record types and most names, without saying anything specific about negative answers. An ISP resolver may offer no public flush at all; then wait, or test through a different resolver.
  5. Clear local caches. On Windows, Microsoft documents ipconfig /flushdns as a way to discard negative cache entries. If one browser still fails while dig shows the new record, restart that browser before blaming DNS.

Deleting and re-creating the record does nothing for resolvers that already cached the NXDOMAIN. They are not asking again until it expires.