Skip to content

SOA Record: syntax, examples, and troubleshooting

The SOA (Start of Authority) record sits at the apex of every zone and carries the zone's administrative metadata: the primary nameserver, the administrator contact, a serial number that drives replication, three secondary-server timers, and a minimum value that today defines negative-cache TTL.

Example SOA record

google.com.		26	IN	SOA	ns1.google.com. dns-admin.google.com. 973049826 900 900 1800 60
cloudflare.com.		300	IN	SOA	ns3.cloudflare.com. dns.cloudflare.com. 2413651619 10000 2400 604800 300
A real SOA record as a resolver returns it
Look one up
SOA Record Lookup

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.

SOA Record Lookup
Zone serial, refresh, and primary nameserver

Every SOA field, explained

Fieldgoogle.com valueWhat 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 \..
SERIAL97304982632-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.
REFRESH900How often a secondary checks the primary's serial, in seconds. Largely superseded by NOTIFY, which pushes changes immediately.
RETRY900How long a secondary waits before retrying after a failed refresh. Should be less than REFRESH.
EXPIRE1800How long a secondary keeps serving the zone with no successful contact with the primary. After this it stops answering entirely — the zone goes dark.
MINIMUM60Originally 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.
MINIMUM is not the default TTL for your records. That role belongs to $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 TTL
The last number in the SOA is how long resolvers will remember that the name does not exist.

A 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 2026090103 for 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) and cloudflare.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}')"
done
Identical serials across all servers means the zone is fully replicated. A laggard is your problem server.

The 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.com does) 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 SOA
Querying SOA for a subdomain reveals the zone cut — useful when you are unsure whether a name is delegated away.

Pair 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.

Frequently asked questions

What is the MINIMUM field in an SOA record?
Since RFC 2308 it is the negative caching TTL — how long resolvers remember that a name in the zone does not exist. It is capped by the SOA record's own TTL. It is not the default TTL for your records, despite the original RFC 1035 wording; that job belongs to $TTL or your provider's per-record setting.
Why does a record I just created still return NXDOMAIN?
Because you probably queried the name before it existed and your resolver cached the negative answer for the zone's MINIMUM value. Query the authoritative nameserver directly with dig @ns1.example.com newname.example.com — if that works, the zone is fine and you are waiting out a negative cache entry.
What serial number format should I use?
Either date-based YYYYMMDDnn or a plain incrementing counter/timestamp. The only rule is that it must increase on every change under RFC 1982 arithmetic. Date-based is readable and self-documenting but caps you at 100 changes a day; counters scale better and are what most managed platforms use.
Can I use the SOA serial to check whether my DNS change has replicated?
Yes, and it is the most reliable check available. Query every nameserver listed in the NS set for the zone's SOA and compare serials. Identical values mean every server has the same zone version. A server with a lower serial has not received your change and will hand out stale records to any resolver that asks it.
Do the REFRESH, RETRY, and EXPIRE values matter on managed DNS?
Usually not. Providers like Cloudflare, Route 53, and NS1 replicate through their own internal systems rather than AXFR, so the published timers are largely cosmetic. They matter when you genuinely run primary and secondary nameservers doing zone transfers, where EXPIRE in particular is a real availability decision.
Can a zone have more than one SOA record?
No. Exactly one SOA exists per zone, at the apex. Multiple SOA records are a malformed zone and most nameservers will refuse to load it. If a subdomain has its own SOA, that means it is a separate delegated zone, not an extra record in the parent.