Defaults.Exposed

What is an SOA record

An SOA record is the one record at the top of your DNS zone that names the primary nameserver, a contact address and five timers governing how copies of the zone stay fresh. Every zone has exactly one, and it’s at the apex rather than on a subdomain. You can pull yours in a second:

$ dig example.com SOA +short
ns1.example.com. hostmaster.example.com. 2026090501 7200 3600 1209600 3600

That single line is the whole record. Seven values in a fixed order, and it’s easy to stop reading after the first one. Hold your own line against the walk-through below and you’ll know which of the seven is doing anything on your domain, and you need that before a checker’s finding means much.

The line a resolver hands back

The order can’t vary. First the primary nameserver (MNAME), then the responsible mailbox (RNAME), then serial, refresh, retry, expire and minimum. Nothing else can appear in an SOA, and a zone can’t carry two of them.

Without +short you’ll also see a TTL on the record itself, 3600 in most zones, which is separate from the numbers inside it. Keep the two apart, because the last of the seven values is the one everyone mistakes for a TTL.

The SOA also does a job you rarely see. Ask a resolver for a name that doesn’t exist in your zone and the negative answer comes back with your SOA in the authority section. That’s how the resolver learns which zone owns the name and how long to remember the absence, so resolvers read a field you thought was inert on each failed lookup against your domain.

Two names before the numbers

ns1.example.com. is the MNAME, the primary nameserver. Secondaries pull the zone from it, and anything doing dynamic DNS updates (a DHCP server, an ACME client updating a validation record) sends its updates there. It’s the server of record, whatever the delegation says.

hostmaster.example.com. is the RNAME, and it’s an email address in disguise. The first dot stands in for the @ sign, so this one reads as [email protected]. If the local part of the address contains a dot, it has to be escaped, so [email protected] is written john\.smith.example.com. in the zone. An unescaped dot silently turns into a different address.

Check whether this field still holds whatever the provider filled in on day one, pointing at a mailbox nobody reads. Changing it is a one-line edit, and it’s the address a stranger will try when your zone is misbehaving and they’re trying to reach a human.

Five timers, in fixed order

2026090501 is the serial, a version number for the zone. The common convention is YYYYMMDDnn, the date plus a two-digit counter, which is what you’re looking at here; some providers use a Unix timestamp instead. The only rule is that it goes up when the zone changes.

7200 is refresh: how often, in seconds, a secondary nameserver asks the primary whether the serial has moved. 3600 is retry: how long the secondary waits after a failed refresh before trying again. 1209600 is expire: how long a secondary keeps answering from its copy when it can’t reach the primary at all. Once expire runs out the secondary stops answering for the zone rather than serve data it can no longer trust.

3600 at the end is the minimum, and since RFC 2308 it has meant one thing: the negative-caching TTL, how long a resolver remembers that a name doesn’t exist. Each record in the zone carries its own TTL; this field doesn’t set them.

Only some of those values reach your users. Resolvers read the last one on each lookup that misses, the serial gets compared whenever someone other than the primary is serving your zone, and the middle three only pass between a primary and its secondaries. Each failure that matters comes from one of those three facts, and the free scan reads your SOA alongside your nameserver set and flags timings that are unusually high or low, so it’s worth running before you go hunting.

A serial that never moves

A secondary decides whether to pull a fresh copy by comparing serials. If the primary’s serial isn’t higher than the one it already holds, it keeps what it has, and a change you made an hour ago is live on one nameserver and absent on another. Resolvers pick nameservers more or less at random, so half your visitors see the new record and half see the old one, for as long as the serial stays put.

A serial gets pinned in one of two ways: someone hand-edits the zone file and forgets to bump the number, or the serial goes backwards, typically when someone reset a YYYYMMDDnn value to 1 or moved a zone between providers with different conventions. Serial comparison uses wrap-around arithmetic on a 32-bit number, so a new serial that is smaller than the old one by any amount, or larger by more than half the 32-bit range, counts as older and gets ignored.

You can see the symptom directly. Ask each of your nameservers for the SOA and compare the serials:

$ dig @ns1.example.com example.com SOA +short
$ dig @ns2.example.com example.com SOA +short

Different numbers mean a stale copy. If the zone is DNSSEC-signed, the stale copy is the more dangerous one, because its signatures keep ageing and a validating resolver returns SERVFAIL the moment they expire; why a signed zone starts failing walks through that case.

The last field and the name that stays missing

Delete a record and republish it, or look up a name a minute before you create it, and any resolver that asked during the gap remembers the absence for up to the minimum value. With 3600 in that slot the name is “missing” for an hour to everyone behind that resolver. With 86400, a common leftover in older zones, it’s missing for a day.

The way this bites in practice is ordinary. You’re adding a TXT record at the apex for your SPF policy, you test the lookup from your laptop before you’ve saved it, get an empty answer, then save. Your resolver hands you the same empty answer on each retry until the negative TTL lapses, and you spend the afternoon convinced the provider dropped the record, when your resolver is only doing what your SOA told it to.

An hour is a sensible ceiling here and there’s little reason to go higher. Resolvers cap the negative cache at the lower of this field and the SOA’s own TTL, so the two 3600s in the example line tend to travel together.

Three timers a hosted provider may ignore

Refresh, retry and expire describe a zone-transfer relationship: a primary, one or more secondaries, and periodic AXFR or IXFR pulls between them. If your DNS provider runs your zone out of its own database and pushes it to its own fleet, no transfer of that kind ever happens, and those three fields are decoration. They can look wrong on a report and change nothing.

They start mattering the moment a real secondary pulls from your primary: a second DNS provider taking transfers for resilience, or a primary you run yourself. Then a short expire is the dangerous value. Set it to 3600 and a one-hour outage on the primary takes the whole domain offline as each secondary gives up in turn. RIPE-203, the long-standing reference for these values, suggests refresh 86400, retry 7200 and expire 3600000, and the 1209600 in the example line (two weeks) is well inside the safe range.

Set them once and don’t tune them for speed. The serial and NOTIFY messages already move a change to secondaries within seconds; refresh is the fallback for when NOTIFY doesn’t arrive.

When the MNAME doesn’t match your NS set

Your NS records, at the parent and in the zone, say who answers for the domain. The MNAME says who holds the master copy. The two are allowed to differ, and one common shape is deliberate: a hidden primary that doesn’t appear in the NS set and only feeds secondaries. That’s a design, and a checker reading the two together will see the mismatch and report it as informational.

The other common shape is an accident. You moved providers, the new one imported the zone verbatim, and the MNAME still names a server at the old provider that has no idea your zone exists. Resolution keeps working because resolvers use the NS set and don’t consult MNAME. The cost shows up when something does consult it: a dynamic-update client sends changes into the void, or the person debugging a fault at 2am spends twenty minutes on a server that stopped mattering a year ago.

A checker notices the mismatch because its nameserver check reads the SOA on the way through. The September 2026 census scanned 347,691,016 domains across 1,433 TLDs and graded 315,211,826 (90.7%) of them, and the nameserver check that ran on those domains picked up the SOA in the same pass. The edition publishes no SOA count, so the line that matters is the one on your own domain.

What to change and what to leave

This is a setting at your DNS provider and correcting it costs nothing. Some providers don’t expose the SOA for editing and ship sane values; if that’s you, the useful checks are the serial comparison above and whether the RNAME reaches anyone. If you can edit it: set RNAME to a mailbox someone reads, let the provider manage the serial (or bump it on each hand edit), keep the minimum at 3600 or lower, and leave refresh, retry and expire alone unless you run secondaries that pull by transfer.

If your report shows the finding beside a nameserver problem, the nameservers fix guide covers the SOA as part of getting the delegation straight, and the rest of the foundation is laid out in the DNS pillar. Read your line first. Most of what looks wrong in an SOA is a field that isn’t doing anything, and the one or two that are can be put right in a single edit.

Figures as of 5 September 2026, from the September 2026 edition of the defaults.exposed census. Census numbers move every month; the current values are on the census data page.