
What Is an SOA Record, and What Do Its Fields Mean?
Every DNS zone on the internet has exactly one SOA record, and most site owners never look at it. Managed DNS providers create it automatically, fill in sensible values, and update it behind the scenes. But the SOA record quietly controls things you do care about: how quickly secondary name servers pick up your changes, how long a "this name doesn't exist" answer gets cached, and whether a backup server will keep answering if your primary goes offline. When something odd happens — a new subdomain that stays missing for hours, or secondaries serving stale data — the SOA is often where the explanation lives.
This article explains what an SOA record is, walks through every one of its seven fields, shows how to read and check it, and covers how to choose good values if you manage your own zones.
What Is an SOA Record?
An SOA record (Start of Authority), defined in RFC 1035, is the record at the top of every DNS zone that describes the zone itself. It identifies the primary source of the zone's data, gives a contact for the zone's administrator, and sets the timers that secondary servers and resolvers use.
Three rules make the SOA different from other records:
- Every zone has exactly one SOA record, and it sits at the zone's apex (the root of the zone, such as
example.com). - It describes the zone, not a host. It doesn't point visitors anywhere.
- It's returned in negative answers. When a resolver asks for a name or record type that doesn't exist, the authoritative server includes the SOA in the response so the resolver knows how long to cache that "no" answer.
If the relationship between zones and domains is fuzzy, the guide on the difference between a DNS zone and a domain is a good primer.
The SOA Record in a Zone File
Here's a typical SOA record as it appears at the top of a BIND-style zone file:
$ORIGIN example.com.
$TTL 3600
@ IN SOA ns1.example.com. hostmaster.example.com. (
2026100101 ; SERIAL
7200 ; REFRESH
3600 ; RETRY
1209600 ; EXPIRE
3600 ) ; MINIMUM (negative caching TTL)
The parentheses let the record span multiple lines, and the comments after each semicolon are ignored by the server. The same record queried with dig appears on one line:
dig SOA example.com +short
ns1.example.com. hostmaster.example.com. 2026100101 7200 3600 1209600 3600
That single line contains all seven fields, in order. Let's go through them.
The Seven SOA Fields
| # | Field | Example | What it controls |
|---|---|---|---|
| 1 | MNAME | ns1.example.com. | The primary name server for the zone |
| 2 | RNAME | hostmaster.example.com. | The administrator's email address, encoded as a name |
| 3 | SERIAL | 2026100101 | The zone's version number |
| 4 | REFRESH | 7200 | How often secondaries check for updates (seconds) |
| 5 | RETRY | 3600 | How long secondaries wait to retry after a failed check |
| 6 | EXPIRE | 1209600 | How long secondaries keep serving data without reaching the primary |
| 7 | MINIMUM | 3600 | How long resolvers cache negative answers |
1. MNAME — the primary name server
The MNAME is the hostname of the primary (master) name server: the server where the authoritative copy of the zone is edited. Secondary servers use it as the source for zone transfers, and DNS UPDATE clients send dynamic updates to it.
On managed DNS platforms with anycast networks, there's often no single "primary" in the traditional sense, so MNAME is simply set to one of the provider's name servers. It usually doesn't need to match anything in particular, but it should be a real, resolvable hostname.
2. RNAME — the responsible person's email
RNAME is an email address written in DNS name format: the @ is replaced with a dot. So hostmaster.example.com. means hostmaster@example.com.
If the local part of the address itself contains a dot, it must be escaped with a backslash:
@ IN SOA ns1.example.com. john\.smith.example.com. ( 2026100101 7200 3600 1209600 3600 )
Here, john\.smith.example.com. represents john.smith@example.com. Without the backslash, it would be read as john@smith.example.com. RFC 2142 recommends using hostmaster as the conventional role address for DNS issues.
3. SERIAL — the zone version
The serial number is a 32-bit unsigned integer that identifies the version of the zone. Every time the zone changes, the serial must increase. Secondary servers compare the serial on the primary with their own copy; if the primary's is higher, they request a zone transfer to get the new data.
The most common convention is YYYYMMDDnn — the date plus a two-digit change counter for that day:
2026100101 first change on 1 October 2026
2026100102 second change the same day
2026100201 first change on 2 October 2026
This format is readable and allows 100 changes per day. Some systems use a plain counter or a Unix timestamp instead. Any scheme works, as long as the number always goes up.
Serials are compared using serial number arithmetic (RFC 1982), which wraps around at 2^32. In practice, that means you can't simply lower a serial you set too high — secondaries will think the lower number is older and ignore it. Fixing that requires either stepping the serial forward through the wraparound in two carefully timed increments, or manually forcing each secondary to reload.
4. REFRESH — how often secondaries check
REFRESH is the interval, in seconds, at which secondary servers query the primary's SOA to see whether the serial has changed. A value of 7200 means every two hours.
In modern setups, REFRESH is mostly a safety net. Primaries send a NOTIFY message (RFC 1996) to secondaries as soon as the zone changes, so secondaries usually update within seconds. REFRESH catches any NOTIFY messages that get lost.
5. RETRY — how long to wait after a failure
If a secondary can't reach the primary during a refresh check, it waits RETRY seconds before trying again, rather than waiting a full REFRESH interval. RETRY should be shorter than REFRESH.
6. EXPIRE — when secondaries give up
EXPIRE is how long a secondary keeps answering queries for the zone if it can't reach the primary at all. Once that time passes with no successful refresh, the secondary stops answering authoritatively for the zone, and queries to it typically return SERVFAIL.
This is a trade-off. A long EXPIRE (two to four weeks is common) keeps your domain resolving through an extended primary outage. A short EXPIRE risks your entire domain disappearing if the primary is down over a long weekend. EXPIRE should be much larger than REFRESH.
7. MINIMUM — the negative caching TTL
This field's name is historical and confusing. Originally it set a minimum TTL for all records in the zone. RFC 2308 redefined it: today it's the negative caching TTL — how long resolvers cache NXDOMAIN ("this name doesn't exist") and NODATA ("this name exists but has no record of that type") answers.
Specifically, resolvers cache negative answers for the lower of the SOA record's own TTL and the MINIMUM value. This is the field behind a familiar frustration: you query new.example.com before creating it, then create it, and it still doesn't resolve for a while. The resolver cached the negative answer. The full mechanism is covered in negative caching in DNS.
Values between 300 and 3600 seconds are typical. Very high values, like a full day, make newly added records painfully slow to appear for anyone who looked them up beforehand.
Recommended SOA Values
There's no single correct set of values, but these are reasonable starting points for a zone with secondaries:
| Field | Typical range | Notes |
|---|---|---|
| REFRESH | 3600–86400 | With NOTIFY in place, a few hours is fine. |
| RETRY | 600–7200 | A fraction of REFRESH. |
| EXPIRE | 1209600–2419200 | Two to four weeks. |
| MINIMUM | 300–3600 | Shorter if you frequently add new records. |
If you use a managed DNS provider, you usually can't change most of these — the provider runs its own replication and controls the timers. Some do let you edit the negative caching TTL, which is the one field most likely to affect you day to day.
How to Check an SOA Record
Query the SOA
dig SOA example.com
Without +short, dig shows the full answer section, including the SOA's own TTL, which affects negative caching alongside MINIMUM.
With PowerShell:
Resolve-DnsName -Name example.com -Type SOA
This returns the fields as named properties — PrimaryServer, NameAdministrator, SerialNumber, TimeToZoneRefresh, TimeToZoneFailureRetry, TimeToExpiration, and DefaultTTL.
Compare serials across all name servers
A mismatch in serial numbers between your name servers means a secondary hasn't picked up your latest changes. dig has a built-in option for this:
dig +nssearch example.com
It queries every authoritative name server listed for the domain and prints each one's SOA serial. All of them should show the same number.
You can do the same check in Python, which is useful for monitoring:
import dns.resolver
domain = "example.com"
serials = {}
for ns in dns.resolver.resolve(domain, "NS"):
ns_name = str(ns.target)
ns_ip = str(dns.resolver.resolve(ns_name, "A")[0])
resolver = dns.resolver.Resolver(configure=False)
resolver.nameservers = [ns_ip]
soa = resolver.resolve(domain, "SOA")[0]
serials[ns_name] = soa.serial
for name, serial in serials.items():
print(f"{name:35} {serial}")
if len(set(serials.values())) > 1:
print("WARNING: name servers are serving different zone versions")
The script looks up each authoritative name server, queries it directly for the SOA, and warns if the serials disagree. Install dnspython with pip install dnspython.
Seeing the SOA in a negative answer
You can watch the SOA being used for negative caching by querying a name that doesn't exist:
dig doesnotexist.example.com A
The response status is NXDOMAIN, and the AUTHORITY section contains the zone's SOA record. That's what tells the resolver how long to cache the non-existence.
Editing the SOA on Your Own Server
If you run your own authoritative DNS — for example, following the guide on running your own DNS server with BIND — the workflow for any zone change is:
- Edit the zone file and increment the SERIAL.
- Validate the zone:
named-checkzone example.com /etc/bind/zones/db.example.com
This parses the file, checks syntax, and prints the serial it loaded. It reports errors like a missing SOA or invalid records before they reach production.
- Reload the zone:
rndc reload example.com
BIND loads the new version and sends NOTIFY messages to secondaries, which then compare serials and transfer the updated zone.
Forgetting step one is the classic mistake: the primary serves the new data, but secondaries see the same serial, assume nothing has changed, and keep serving the old zone.
Common Mistakes and Best Practices
- Not incrementing the serial. Secondaries ignore your change. Some tools and providers handle this automatically; with hand-edited zone files, make it a habit.
- Setting the serial too high by mistake. Typing an extra digit can leave you with a serial that's hard to recover from. Double-check before reloading.
- A very short EXPIRE. If your primary goes down, your secondaries stop answering and your domain goes offline.
- A very long negative caching TTL. New records take a long time to become visible to anyone who queried them before they existed.
- An RNAME with an unescaped dot. The contact address becomes wrong.
- Treating MINIMUM as a default TTL. That was its original meaning, but modern resolvers use it only for negative caching. Use
$TTLin the zone file for the default record TTL.
SOA Record FAQ
SOA stands for Start of Authority. It's the record at the top of every DNS zone that identifies the primary name server, the administrator's contact, and the timers for the zone.
No. Every zone has exactly one SOA record, located at the zone apex. A zone without one, or with more than one, is invalid.
The serial is the version number of the zone. Secondary name servers compare it with their own copy and request a zone transfer when the primary's serial is higher.
It's a convention where the serial is the date of the change followed by a two-digit counter, such as 2026100101 for the first change on 1 October 2026. It's readable and always increasing.
Since RFC 2308, it sets the negative caching TTL: how long resolvers cache answers saying a name or record type doesn't exist. Resolvers use the lower of this value and the SOA record's own TTL.
DNS stores the contact address as a domain name, so the at sign is replaced by the first dot. For example, hostmaster.example.com. means hostmaster at example.com.
Usually only partially, if at all. Managed providers generate the SOA and control replication timers. Some allow changes to the negative caching TTL or contact address.
A secondary hasn't received the latest version of the zone. Common causes are a lost NOTIFY, a firewall blocking zone transfers, or a serial that wasn't incremented properly.
Conclusion
The SOA record is the zone's control panel. Its seven fields name the primary server and the person responsible, version the zone through the serial, govern how secondaries stay in sync through REFRESH, RETRY, and EXPIRE, and set how long resolvers remember that something doesn't exist. Most of the time it works silently, which is exactly how it should be.
If you use a managed DNS provider, the field most worth knowing is MINIMUM, because it explains why newly created records sometimes take a while to appear. If you run your own name servers, the serial is the one to respect: increment it with every change, validate with named-checkzone, and confirm with dig +nssearch that every server agrees on the version you just published.
Here are some useful references for going deeper on SOA records:
- RFC 1035: Domain Names - Implementation and Specification — the original definition of the SOA record and its fields.
- RFC 2308: Negative Caching of DNS Queries (DNS NCACHE) — redefines the SOA MINIMUM field as the negative caching TTL.
- RFC 1982: Serial Number Arithmetic — how SOA serials are compared and how wraparound works.
- RFC 1996: A Mechanism for Prompt Notification of Zone Changes (DNS NOTIFY) — how primaries tell secondaries that a zone changed.
- BIND 9 Administrator Reference Manual: bind9.readthedocs.io — zone file syntax,
named-checkzone, andrndcreference.


