I spend a bit of time explaining the DNS Start Of Authority (SOA) record in introductory DNS trainings. This is what a DNS SOA record (the first record in a zone file and one which must exist exactly once in a zone) looks like:

example.net.   3600 IN  SOA mname rname (
                        17       ; serial
                        7200     ; refresh (2 hours)
                        3600     ; retry (1 hour)
                        1209600  ; expire (2 weeks)
                        900      ; negttl [minimum] (15 minutes)

We discuss the individual fields and scenarios for their values (also pointing out that recommended SOA values may or may not be useful). I specifically talk about the expire field and what its use is. You will know that if a secondary server for this zone cannot contact a primary for expire seconds, the secondary server will no longer respond to queries for this zone, preferring to SERVFAIL rather than to respond with stale data. That is how I learned what the field means. Quite straightforward actually.

I would not have brought up the topic had it not been for a participant who asked what happens if expire is configured to zero (0) seconds.

After saying “don’t do that!” and threatening to get a frozen trout from the fridge if further such question arose, I put the question aside, but that evening I decided to investigate. Unfortunately, as it turns out.

DNS specifications and exceptions ... ;)

Shaft points out that Wikipedia says:

This value must be bigger than the sum of Refresh and Retry

but that there’s no source for the statement, nor is there an affirmation in RFCs 1034,1035.

What would actually happen if an authoritative primary provided a zone with expire=0 in its SOA?

My first thought was the secondary server, upon receiving a transfer with expire=0, would just immediately expire the zone. Easy enough to test, and it turned out that a BIND secondary does not do that at all but continues serving the zone “for a while”. (I initially reported BIND serves the zone for an hour before expiring it, but that is wrong.) Thanks to Evan who directs me to the function I wasn’t able to find in the source code, I learn expire is set to at least refresh + retry (and has been since 1999), whereby the latter two values have a minimum of 5 minutes each. I also learned that BIND limits expire to 14515200 seconds or 24 weeks.

The introductory training had already finished, but I contacted the participants and reported our findings. (I try to not leave questions unanswered.)

And how do the other Open Source DNS servers react?

PowerDNS and Knot DNS do not expire the zone data when receiving expire=0; the former because it doesn’t ever expire a zone (see below).

Admittedly this whole topic of expire with value 0 seconds is super edge-case, and there’s no reason to get involved in looking into it. (So why did I do that!?!?)

But what about “regular” expiration? Assume a zone has a valid expire field in its SOA, how will these servers handle that when operating as secondaries?

PowerDNS originally made a deliberate design choice to never expire zones. I learned about this yesterday upon submitting an issue report.

NSD implements zone expiry and logs the fact when it occurs. (Here are notes I took.)

nsd[45521]: error: xfrd: zone a1.dnslab.org has expired

Knot DNS also expires the zone when expire elapses, logging the fact (my notes).

info: [a1.dnslab.org.] zone expired

BIND also expires the zone when the SOA expire elapses (my notes), and logs the fact:

general: zone a1.dnslab.org/IN: expired

These last three respond with SERVFAIL when the zone has expired, meaning that a legitimate client such as a resolver will attempt to query a different nameserver.

I spent the better part of a day doing this. I should have left it at don’t do that!