Type something to search...
What is an SOA record and what do its fields mean?

What is an SOA record and what do its fields mean?

An SOA (Start of Authority) record is the first and mandatory record in every DNS zone. It identifies the zone's primary nameserver and the administrator's contact address, and it holds a serial number plus four timers that control how secondary nameservers keep their copies up to date and how long resolvers cache negative answers. Every zone has exactly one SOA record, at its apex, and DNS software won't load a zone without it.

Most people never edit an SOA record, because hosted DNS providers manage it for you. But if you run your own nameservers, use secondary DNS, or are troubleshooting why a missing record seems to stay missing, the SOA fields matter. In this article you'll learn what each of the seven fields means, how the serial number works and how to recover when it goes wrong, sensible values for the timers, how the SOA record shows up in negative answers, and how to inspect it with dig.

What an SOA Record Looks Like

Here's a typical SOA record in a BIND-style zone file:

$ORIGIN example.com.
$TTL 3600
@   IN  SOA  ns1.example.com. hostmaster.example.com. (
             2026101301 ; serial
             7200       ; refresh (2 hours)
             3600       ; retry (1 hour)
             1209600    ; expire (2 weeks)
             3600       ; minimum / negative caching TTL (1 hour)
             )

The parentheses just let the record span several lines. It contains seven fields after the type:

FieldExamplePurpose
MNAMEns1.example.com.The primary nameserver for the zone
RNAMEhostmaster.example.com.The administrator's email address, written as a name
SERIAL2026101301The version number of the zone
REFRESH7200How often secondaries check for changes
RETRY3600How long a secondary waits after a failed check
EXPIRE1209600How long a secondary keeps serving data without reaching the primary
MINIMUM3600The TTL for negative answers

All of the timers are in seconds and stored as 32-bit numbers.

The Name Fields

MNAME: The Primary Nameserver

MNAME names the primary (master) server, the original source of the zone's data. Secondary servers pull their copies from it, directly or indirectly. It's also where clients send dynamic DNS updates (RFC 2136) when they need to find the server that accepts changes.

MNAME doesn't have to appear in the zone's NS records. Some setups use a hidden primary: a server that isn't listed publicly and only feeds the public secondaries. In that case MNAME may name the hidden server or one of the public ones, depending on what the operator prefers.

RNAME: The Responsible Person's Email

RNAME is an email address written in DNS name format, with the first dot standing in for the @. So hostmaster.example.com. means hostmaster@example.com.

If the local part of the address contains a dot, escape it with a backslash:

; john.smith@example.com
@   IN  SOA  ns1.example.com. john\.smith.example.com. ( ... )

Use a role address such as hostmaster@ rather than a person's mailbox, so it survives staff changes, and make sure it actually receives mail.

The Serial Number

The serial is the zone's version number. Every time the zone changes, the serial must go up. Secondary servers compare their serial with the primary's, and only transfer the zone when the primary's is higher.

Serial Formats

DNS doesn't mandate a format, only that the number increases. Three conventions are common:

  1. Date-based (YYYYMMDDnn): For example 2026101301 for the first change on 13 October 2026. It's human-readable and allows 100 changes a day.
  2. Unix timestamp: For example 1792112400. Good for automated systems that change the zone often.
  3. Simple counter: 1, 2, 3 and so on. Perfectly valid, just less informative.

If BIND manages your zone through dynamic updates, it can maintain the serial for you. The serial-update-method option in a zone block accepts increment, unixtime or date:

zone "example.com" {
    type primary;
    file "/var/lib/bind/db.example.com";
    update-policy local;
    serial-update-method date;
};

Serial Number Arithmetic

Serials are compared using serial number arithmetic (RFC 1982), which treats the 32-bit space as a circle. A new serial counts as "greater" than the old one if it's ahead by less than 2^31 (2,147,483,648). That has two consequences:

  • You can't increase a serial by more than 2,147,483,647 in one step, or secondaries will think it went backwards.
  • If you decrease a serial, secondaries will consider their copy newer and ignore yours.

Fixing a Serial That's Too High

A common accident is setting a date-based serial in the wrong year, for example 2027101301 instead of 2026101301. You can't just lower it. Instead, use the two-step method that serial arithmetic allows:

  1. Add 2,147,483,647 to the current serial. 2027101301 + 2147483647 = 4174584948. Publish that and wait until every secondary has transferred it.
  2. Set the serial you actually want. Because the counter wraps around, 2026101302 now counts as greater than 4174584948. Publish it and let the secondaries transfer again.

Check each step with the commands later in this article before moving on. If you control every secondary, a simpler alternative is to delete the zone on the secondaries and force a fresh transfer.

Hosted Providers

Managed DNS services handle the serial internally, and some don't use it in the traditional way at all. Their SOA serial may stay constant or change on every edit. That's fine for zones served only by the provider's own network. It only matters if you add a third-party secondary that relies on the serial to know when to transfer.

The Timers

The four timers mostly concern secondary nameservers that copy the zone from the primary.

REFRESH

How often a secondary asks the primary for the SOA record to see whether the serial has changed. If the serial is higher, the secondary requests a zone transfer.

In practice, most primaries also send a NOTIFY message (RFC 1996) to secondaries as soon as the zone changes, so updates propagate within seconds. REFRESH is the safety net for when a NOTIFY is lost.

RETRY

If a refresh check fails because the primary is unreachable, the secondary waits RETRY seconds before trying again. It should be shorter than REFRESH.

EXPIRE

If a secondary can't reach the primary for EXPIRE seconds in total, it stops answering for the zone, on the basis that its data may now be dangerously stale. Resolvers then get errors from that server. EXPIRE should be long, typically one to four weeks, so a primary outage doesn't take the whole zone down.

MINIMUM: The Negative Caching TTL

Despite its name, this field no longer sets a minimum TTL for the zone. RFC 2308 redefined it as the negative caching TTL: how long resolvers may cache an answer saying a name doesn't exist (NXDOMAIN) or has no records of the requested type (NODATA).

More precisely, the negative TTL is the lower of the SOA record's own TTL and the MINIMUM field. With the example above, both are 3600, so a resolver that asks for a missing name will remember that it's missing for up to an hour. If you then create the record, users of that resolver won't see it until the negative entry expires.

Recommended Values

There's no single correct set of values, but these are sensible starting points for most zones:

FieldTypical rangeSuggested starting point
REFRESH1 to 24 hours7200 (2 hours)
RETRYShorter than REFRESH3600 (1 hour)
EXPIRE1 to 4 weeks1209600 (2 weeks)
MINIMUM5 minutes to 1 day3600 (1 hour)

A few relationships should always hold:

  • RETRY is less than REFRESH.
  • EXPIRE is much larger than REFRESH plus RETRY, so a secondary gets many chances to reach the primary before giving up.
  • MINIMUM is short enough that newly created names don't stay invisible for long. Values of a day or more were once common but cause real pain when you add records.

Checking Timers With a Script

This Python script fetches a zone's SOA record and flags values that break those relationships:

import sys

import dns.resolver


def check_soa(zone):
    answer = dns.resolver.resolve(zone, "SOA")
    soa = answer[0]
    print(f"Zone:     {zone}")
    print(f"MNAME:    {soa.mname}")
    print(f"RNAME:    {soa.rname}")
    print(f"Serial:   {soa.serial}")
    print(f"Refresh:  {soa.refresh}")
    print(f"Retry:    {soa.retry}")
    print(f"Expire:   {soa.expire}")
    print(f"Minimum:  {soa.minimum}")
    print(f"SOA TTL:  {answer.rrset.ttl}")

    problems = []
    if soa.retry >= soa.refresh:
        problems.append("RETRY should be lower than REFRESH")
    if soa.expire < 7 * 86400:
        problems.append("EXPIRE is under a week")
    if soa.expire <= soa.refresh + soa.retry:
        problems.append("EXPIRE should be far larger than REFRESH + RETRY")
    if min(soa.minimum, answer.rrset.ttl) > 86400:
        problems.append("Negative caching TTL is over a day")

    for problem in problems:
        print(f"WARNING:  {problem}")
    if not problems:
        print("Timers look sensible.")


check_soa(sys.argv[1] if len(sys.argv) > 1 else "example.com")
pip install dnspython
python soa_check.py example.com

Note that the TTL printed may be lower than the configured value if the answer came from a resolver's cache. Some large operators that don't use traditional zone transfers publish unusual timer values on purpose, so treat a warning as a prompt to look closer rather than proof of a problem.

Viewing an SOA Record

With dig

dig example.com SOA +multiline +noall +answer

The +multiline option labels each field:

example.com.        3600 IN SOA ns1.example.com. hostmaster.example.com. (
                                2026101301 ; serial
                                7200       ; refresh (2 hours)
                                3600       ; retry (1 hour)
                                1209600    ; expire (2 weeks)
                                3600       ; minimum (1 hour)
                                )

Comparing Serials Across Nameservers

The +nssearch option asks every authoritative nameserver for the SOA record, which is a quick way to see whether they're all serving the same version:

dig example.com +nssearch
SOA ns1.example.com. hostmaster.example.com. 2026101301 7200 3600 1209600 3600 from server 203.0.113.53 in 18 ms.
SOA ns1.example.com. hostmaster.example.com. 2026101301 7200 3600 1209600 3600 from server 198.51.100.53 in 24 ms.

If one server shows an older serial, it hasn't picked up the latest change. Check that NOTIFY and zone transfers between your primary and that secondary are working.

The SOA Record in Negative Answers

When a name doesn't exist, the authoritative server includes the zone's SOA record in the authority section of the response. That's how resolvers know which negative TTL to apply:

dig nothing-here.example.com A
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 41377
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; AUTHORITY SECTION:
example.com.        3600    IN  SOA  ns1.example.com. hostmaster.example.com. 2026101301 7200 3600 1209600 3600

When this comes from a caching resolver, the TTL shown counts down, telling you how long the "doesn't exist" answer will stay cached.

Editing the SOA on Your Own Servers

When you edit a zone file by hand, the workflow is always the same: make the change, increase the serial, validate, and reload.

sudo named-checkzone example.com /etc/bind/zones/db.example.com
zone example.com/IN: loaded serial 2026101302
OK
sudo rndc reload example.com
sudo rndc notify example.com

The named-checkzone output confirms the serial BIND will load. If you forget to raise it, the primary will serve the new data but secondaries won't fetch it, and different nameservers will give different answers until someone notices. Many teams avoid the problem entirely by generating zone files from a template or managing records through an API.


FAQ: SOA Records

No. Each zone has exactly one SOA record, and it must be at the zone apex. Subdomains that are delegated as separate zones have their own SOA records.

Usually not. Hosted providers manage the serial and timers automatically. The main reason to adjust them is if you add a third-party secondary or want a shorter negative caching TTL, and only some providers let you edit those values.

DNS stores RNAME as a domain name, so the at sign is replaced by the first dot. hostmaster.example.com. therefore means hostmaster@example.com. Dots in the local part must be escaped with a backslash.

Secondary nameservers won't notice the change and will keep serving the old data, while the primary serves the new data. Visitors then get different answers depending on which server they reach.

Not any more. That was its original meaning, but RFC 2308 changed it to the negative caching TTL. Record TTLs are now set individually or with the $TTL directive in zone files.

If someone looked up the name before it existed, their resolver cached the negative answer for the negative TTL, which comes from the SOA record. They won't see the new record until that cached entry expires.


Conclusion

The SOA record is a small block of metadata with a big job. MNAME and RNAME say who runs the zone, the serial tells secondaries when something has changed, REFRESH, RETRY and EXPIRE govern how they stay in sync, and MINIMUM decides how long resolvers remember that a name doesn't exist.

If you use a managed DNS provider, it's mostly a record to understand rather than edit. If you run your own servers, treat the serial with care, keep the timer relationships sensible, and use dig +nssearch to confirm that every nameserver agrees. Those habits prevent most of the confusing, half-updated states that zones can otherwise get into.

Tags :
Share :

Related Posts

What is the difference between an A record and a CNAME record?

What is the difference between an A record and a CNAME record?

The difference between an A record and a CNAME record is what they point to. An A record points a hostname directly at an IPv4 address, such

Dive Deeper
What are the best DNS providers for websites?

What are the best DNS providers for websites?

The best DNS providers for most websites are Cloudflare for a fast, free, easy starting point, Amazon Route 53 if you already run on AWS, **G

Dive Deeper
What are the best public DNS resolvers?

What are the best public DNS resolvers?

The best public DNS resolvers for most people are Cloudflare (1.1.1.1) for speed and privacy, Google Public DNS (8.8.8.8) for reliability and

Dive Deeper