What does the SOA record do?
SOA is record type 6 from RFC 1035. Exactly one exists per zone, always at the apex, and its presence is what makes a name a zone boundary rather than just another label. Delete it and the zone does not load.
Two audiences read it. Secondary nameservers — the hosts listed in the zone's NS records — use the serial and the timers to decide when to pull a fresh copy of the zone from the primary. Recursive resolvers use the record in a completely different way: when a name does not exist, the authoritative server returns NXDOMAIN with the SOA in the authority section, and the resolver uses that SOA to decide how long to remember the non-existence.
Every SOA field, explained
| Field | google.com value | What it means |
|---|---|---|
| MNAME (primary) | ns1.google.com. | The primary master for the zone. Used as the target for dynamic updates and NOTIFY. It does not have to be listed in the NS set, though it usually is. |
| RNAME (contact) | dns-admin.google.com. | Administrator email with the @ replaced by a dot — this is [email protected]. A dot inside the local part is escaped as \.. |
| SERIAL | 973049826 | 32-bit unsigned counter. Secondaries transfer the zone only when the primary's serial is higher than theirs, using serial-number arithmetic (RFC 1982) so it can wrap. |
| REFRESH | 900 | How often a secondary checks the primary's serial, in seconds. Largely superseded by NOTIFY, which pushes changes immediately. |
| RETRY | 900 | How long a secondary waits before retrying after a failed refresh. Should be less than REFRESH. |
| EXPIRE | 1800 | How long a secondary keeps serving the zone with no successful contact with the primary. After this it stops answering entirely — the zone goes dark. |
| MINIMUM | 60 | Originally a default TTL for the zone. Since RFC 2308 it is the negative caching TTL: how long resolvers remember NXDOMAIN for names in this zone. |
$TTL in a zone file, or to the per-record TTL your provider sets. MINIMUM only controls how long a negative answer is cached.The MINIMUM field and negative caching
RFC 2308 redefined MINIMUM as the negative-cache TTL, capped by the TTL of the SOA record itself — a resolver caches an NXDOMAIN for the lesser of the two. This has a direct operational consequence that catches people out constantly.
Suppose you check newapp.example.com before creating it. The lookup returns NXDOMAIN, and your resolver caches that non-existence for the zone's MINIMUM. You then create the record — and the name still fails to resolve for you, even though the zone is correct, until the negative cache expires. Query the authoritative server directly and it works fine. It is not a propagation problem in any meaningful sense; it is a negative answer you caused yourself.
# An NXDOMAIN response carries the SOA in the authority section
dig +noall +authority nonexistent-xyzq.google.com A
# google.com. 60 IN SOA ns1.google.com. dns-admin.google.com. 973049826 900 900 1800 60
# ^^ negative-cache TTLA MINIMUM of 60–300 is a good default for a zone under active change. Very large values (the old 86400 convention) mean a typo checked before it was fixed haunts you for a day. This distinction is central to telling a caching problem apart from a real one — see SERVFAIL vs NXDOMAIN, and Why is my DNS not propagating? for the wider checklist.
Serial number formats
The only hard requirement is that the serial increases when the zone changes, using RFC 1982 serial arithmetic. Two conventions dominate:
- Date-based, `YYYYMMDDnn` — for example
2026090103for the third change on 1 September 2026. Human-readable and self-documenting, which is why it is the classic BIND convention. Its limit is 100 changes per day, and it fails awkwardly if you exceed that. - Unix timestamp or a plain counter — what
google.com(973049826) andcloudflare.com(2413651619) both use. Managed DNS platforms almost always do this because they push changes far more often than 100 times a day.
Whatever the format, the serial is a superb diagnostic. Query every nameserver for the zone and compare serials: if one server is behind, that server has not received your change, and any resolver that happens to ask it will return stale data. That is the mechanism behind a large share of "it works for some people" reports.
# Compare the serial across every authoritative nameserver
for ns in $(dig +short google.com NS); do
printf '%-20s %s\n' "$ns" "$(dig +short @"$ns" google.com SOA | awk '{print $3}')"
doneThe secondary timers in practice
REFRESH, RETRY, and EXPIRE only matter if you actually run secondary nameservers doing zone transfers. On a managed DNS platform the values you see are decorative — the provider replicates over its own internal mechanism and the SOA timers are published because the record requires them.
If you do run primary/secondary with AXFR/IXFR:
- REFRESH of 3600–7200 is typical, but NOTIFY makes it near-irrelevant — the primary pushes a message the moment the zone changes and the secondary refreshes immediately. REFRESH is the fallback for when NOTIFY is lost.
- RETRY should be comfortably shorter than REFRESH; 900–1800 is normal.
- EXPIRE is a real availability decision. Setting it to 604800 (a week, as
cloudflare.comdoes) means secondaries keep serving for seven days if the primary vanishes. Setting it low means the zone goes dark quickly during an outage. Err long. - EXPIRE must exceed REFRESH and RETRY by a wide margin, or a couple of failed transfers will expire a zone that is otherwise fine.
Common SOA mistakes
- Editing the zone without bumping the serial. Secondaries never pull the change, and you get a permanent split brain between primary and secondary. Any tooling that writes zone files must bump the serial in the same operation.
- Bumping the serial backwards. Switching from a timestamp to a date-based serial usually makes the number smaller, and secondaries then ignore every subsequent update. Fix it by setting the serial to a value clearly above the old one, or follow the RFC 1982 two-step wraparound procedure.
- Treating MINIMUM as the record TTL. Covered above — it is the negative-cache TTL.
- A very large MINIMUM. 86400 means a mistyped hostname you tested before publishing stays NXDOMAIN in resolver caches for a day.
- An RNAME that is not a real mailbox.
hostmaster.example.com.is the convention; make sure something actually receives mail there, since it is the contact of last resort for DNS problems. - Forgetting that `@` in RNAME becomes a dot.
dns-admin.google.com.is[email protected], not a hostname. - EXPIRE shorter than a plausible outage. A 3600 EXPIRE means a one-hour primary outage takes the whole zone offline on every secondary.
Check it with dig
# The zone's SOA
dig +short google.com SOA
# With TTL and full formatting
dig +noall +answer cloudflare.com SOA
# Straight from an authoritative server, no cache
dig +noall +answer @ns1.google.com google.com SOA
# What SOA is returned for a name that does not exist
dig +noall +authority doesnotexist.google.com A
# Which zone does a subdomain belong to? The SOA name tells you
dig +short mail.google.com SOA
dig +noall +authority mail.google.com SOAPair this with the NS lookup to see which servers should be answering, DNS Compare to see whether public resolvers agree, and the propagation checker for a global view.