Start with the stage that owns the fact.
A customer can report a missing name while the database, update worker, nameserver set, authoritative server, recursive resolver, and client each hold a different state. Dave Pacheco's account of Oxide's DNS system lists those stages and the evidence its debugger reports for each one. The useful output names the configuration generation, discovery time, target servers, attempt time, and per-server result.[1]
That is stronger than a green "DNS healthy" badge. It can locate the break. It can also clear a stage by showing the exact version it handled and when.
Ask which server answered, what it answered, and how long that answer can live.
The authoritative answer and the cached answer are different observations.
dig @server name type directs a query to a named server. Without a server argument, BIND's dig uses the resolver listed by the host. The command also exposes the response code, flags, answer sections, and TTLs.[2]
Use that distinction. Query each authoritative nameserver directly. Then query the recursive resolver used by the affected client. If the authority has the new record and the resolver returns the old one with a falling TTL, the update path and cache path are not telling the same story.
An empty answer can remain cached.
RFC 2308 defines negative caching for NXDOMAIN and NODATA responses. An authoritative negative response carries the zone's SOA record. The negative TTL is the smaller of the SOA TTL and its MINIMUM field. A recursive resolver decrements that value while the negative answer remains cached.[3]
This matters when a client queried a name before it existed. Adding the record does not erase the earlier negative answer from every recursive cache. Record the response code and SOA values instead of writing "still broken."
Expired does not always mean gone.
Some DNS paths can return stale cached data when an upstream server is slow or returns SERVFAIL. Cloudflare documents this behavior for flattened CNAME lookups and Workers subrequests. In that case, the service can return an expired answer while it refreshes the cache in the background.[4]
Do not infer every resolver's policy from that example. Record whether stale serving is enabled on the resolver you operate. If you do not operate it, label that policy unknown.
Save a compact witness packet.
QNAME=[REQUIRED]
QTYPE=[REQUIRED]
EXPECTED_RDATA=[REQUIRED]
CHANGE_TIME_UTC=[REQUIRED]
AUTHORITATIVE_SERVER=[REQUIRED]
AUTHORITATIVE_RCODE_TTL_RDATA=[REQUIRED]
RECURSIVE_SERVER=[REQUIRED]
RECURSIVE_RCODE_TTL_RDATA=[REQUIRED]
CLIENT_RESOLVER_PATH=[REQUIRED]
SOA_SERIAL_AND_NEGATIVE_TTL=[IF_NEGATIVE]
STALE_SERVING_POLICY=[KNOWN_OR_UNKNOWN]
CAPTURE_TIME_UTC=[REQUIRED]
The rack below drafts this packet. It does not query DNS, clear a cache, or prove a change reached production.