TinyDNS tinydns.org

How DNS resolves a name, and how the servers that do it are run.

The countdown starts the moment you get the answer

Negative answers are cached too

The absence of a record is itself an answer with a lifetime, and it is the one people forget.

A terminal window showing an empty query result on a dark screen
Nothing in this room counts down for you. The countdown runs inside caches you do not operate.Photograph

The NXDOMAIN cache hit you did not expect

When a resolver asks for a record that does not exist, the authoritative server says so — and the resolver caches that statement. It is not a gap in the cache; it is a positive entry asserting absence. Every subsequent query for the same name returns the cached denial without touching the wire, until the TTL attached to that denial expires. This is negative caching, and RFC 2308 ↗ formalised the mechanism in 1998. Before that, implementations handled it inconsistently, and resolvers that cached nothing at all would hammer authoritative servers with repeated questions about nonexistent names.

Two kinds of negative answer exist. An NXDOMAIN says the name itself does not exist. A NOERROR with an empty answer section — sometimes called NODATA — says the name exists but carries no record of the requested type. Both get cached. Both carry a TTL that the resolver derives from the SOA record returned in the authority section of the negative response, specifically the SOA's MINIMUM field, capped at whatever the SOA's own TTL is. That SOA minimum is the operator-controlled knob for negative TTL, and many operators set it once and never revisit it.

A hand-annotated zone file printout on a desk beside a keyboard
The serial at the top of the file is the one line a secondary reads before deciding whether to pull anything at all.Photograph

Why it bites you during a migration

A record goes live. Queries that arrived before the record was published were answered with NXDOMAIN, and those answers are now sitting in caches with their original TTLs still counting down. The zone is authoritative, the record is real, but anyone whose resolver holds a cached denial will keep getting that denial — not because anything is broken, but because the protocol is working exactly as designed.

The standard preparation — lowering the TTL before you move anything — addresses TTL for positive records. Negative TTL is the companion problem. If the SOA MINIMUM is set to 3600 and you publish a new name that previously did not exist, any resolver that queried for it in the hours before you added it will cache NXDOMAIN for a full hour. There is no way to push an invalidation to foreign caches; you wait.

The lever is the SOA MINIMUM field. RFC 2308 recommends values between one and three hours for most zones, and somewhere between one and five minutes for zones in active development or migration. A low negative TTL increases authoritative query load in proportion to query volume against nonexistent names — a real cost if the zone attracts significant NXDOMAIN traffic from typos or probing. The right value is a balance, not a default you borrow from a template.

DNSSEC changes the shape, not the problem

DNSSEC adds authenticated denial of existence through NSEC and NSEC3 records, which cryptographically prove that no name exists between two signed points in the zone. The resolver can verify that the denial is genuine and not injected. What DNSSEC does not change is the caching behaviour: a validated NXDOMAIN is still cached for the same TTL, and still blocks queries for the same duration after the underlying zone changes. Signing the denial makes it trustworthy, not short-lived. The NSEC and NSEC3 specifications ↗ also introduce a side-effect known as zone enumeration, which is why NSEC3 was developed — but none of that touches the TTL arithmetic.

The practical discipline is straightforward: treat negative TTL as a first-class parameter. Before introducing any new name into a zone, check the SOA MINIMUM and reduce it if the name might already have attracted NXDOMAIN caching. After the record is live and cache entries have expired, you can raise it again. The absence of a record is an answer the whole internet will believe for exactly as long as you told it to.

Queries that arrived before the record was published were answered with NXDOMAIN, and those answers are now sitting in caches with their original TTLs still counting down.

An adult engineer at an open rack door in an exchange-point facility, hand on a labelled cable
Cable labels are the only place a delegation is written down in the physical world. Where they disagree with the zone, the zone wins and nobody finds out for months.Photograph

Before that, implementations handled it inconsistently, and resolvers that cached nothing at all would hammer authoritative servers with repeated questions about nonexistent names.

Read next, in this section