What the SOA Record Actually Does
The Start of Authority record is the first record in any DNS zone file. It's the record that says "this zone exists, this is the primary nameserver in charge, and here are the timing rules that govern how this zone behaves."
A full SOA record looks like this when you query it:
example.com. 86400 IN SOA ns1.example.com. admin.example.com. (
2024042801 ; Serial
3600 ; Refresh
900 ; Retry
1209600 ; Expire
300 ; Minimum TTL
)Each of those numbers does something different. The one that triggered your warning is the Expire value, the fourth number. In this example, 1209600 seconds, which is exactly 14 days.
Here's what each field controls, because they're easy to confuse:
Serial: The version number for your zone. Secondary nameservers check this to decide whether they need to pull a fresh copy. Every time you make a change to your zone, this number needs to go up.
Refresh: How often secondary nameservers poll the primary to ask "do you have anything new?" 3600 seconds is one hour.
Retry: If a secondary couldn't reach the primary during a refresh attempt, how long it waits before trying again. Should be shorter than Refresh.
Expire: How long a secondary nameserver keeps serving your zone data if it completely loses contact with the primary. This is the one we're here to talk about.
Minimum TTL: The negative caching TTL. This is how long resolvers cache a "this record doesn't exist" response for your zone.
Say your primary nameserver at ns1.example.com goes offline at 9am Monday. Hardware failure, doesn't matter why.
Your secondary at ns2.example.com last synced successfully at 8am. The Refresh timer (3600 seconds) fires at 9am and the secondary tries to reach the primary. No response. The Retry timer kicks in: try again in 900 seconds. Still nothing. It keeps retrying on that 900-second cycle.
Meanwhile, ns2 keeps serving your zone normally. Visitors resolve your domain fine. Nobody knows anything is wrong yet.
Tuesday morning your team makes a DNS change, adding a new A record, and they do it through a backup control panel that writes to the primary. But ns1 is still offline, so the serial number on the primary increments to 2024042901 and just sits there. ns2 never finds out the record was added because it can't reach the primary to compare serials.
By Thursday, you've had the primary offline for four days. ns2 is still serving the old zone data. The new A record you added Tuesday is invisible to the outside world. Nobody is getting SERVFAIL yet because the Expire timer (1,209,600 seconds, 14 days) is still counting down.
This is the quiet phase. DNS looks fine from the outside. Your zone is just slowly diverging from reality.
If you restore ns1 before the 14-day expire deadline, ns2 does a zone transfer, picks up the new serial, syncs everything, and the gap closes. Most people never notice this happened.
If you don't restore ns1 within 14 days, ns2 hits the expire deadline and stops answering authoritative queries for your zone. No more A records, no more MX records, nothing. SERVFAIL. Email stops delivering. Your site goes dark from a DNS perspective — the Minimum TTL (300 seconds) means resolvers are only caching negative responses for 5 minutes, so the SERVFAIL answers spread quickly.
That sequence, from the quiet divergence to the eventual outage, is exactly what the expire timer is managing. 14 days is the line between "resilient infrastructure" and "stop serving this stale data."
What the Expire Value Actually Controls
Secondary nameservers are copies of your zone. They exist for redundancy and to distribute query load. Under normal operation, they stay in sync by polling your primary nameserver on the Refresh interval, requesting zone transfers when the serial number has changed.
Now picture your primary nameserver going completely offline. Hardware failure, data center problem, whatever the reason. Your secondary nameservers are now on their own. They still have a copy of your zone data, and they'll keep serving it. But for how long?
That's what the Expire value answers. It's a hard deadline. Once that timer runs out without the secondary being able to contact the primary, the secondary stops answering authoritative queries for your zone entirely. It starts returning SERVFAIL instead.
This is intentional behavior. The logic is that at some point, stale zone data is worse than no answer at all. If your secondary has been serving records that are weeks old without being able to verify them, those records might be dangerously wrong. SERVFAIL is honest. Serving stale data is not.
The Expire timer starts counting down from the last successful contact with the primary, not from when the primary went down.
That last point matters more than it sounds. If your Refresh interval is one hour and your primary goes down at 9:02am, right after a successful sync at 9:00am, your secondary has a nearly full 14-day clock.
But if your primary goes down at 8:59am, one minute before the scheduled sync, and the secondary's last successful contact was the previous hour, you've already burned an hour off that clock before the outage even registered.
In practice, with a one-hour Refresh interval, you're looking at up to 59 minutes of silent gap before a secondary even knows the primary is unreachable. Then the Retry cycle starts, not a continuous hammer, just periodic attempts every 900 seconds based on the Retry value in your SOA record.
The secondary keeps serving your zone the entire time. From the outside, nothing looks wrong.
There's another angle worth understanding. The expire timer is zone-specific, not nameserver-specific. If you're running multiple zones on the same secondary nameserver and one zone has a misconfigured expire value while others don't, only that zone goes dark when the deadline hits. The nameserver stays up. Other zones keep resolving. The failure is surgical in a way that makes it easy to misdiagnose. Your monitoring pings the nameserver, gets a response, and marks it healthy, while one specific domain is silently returning SERVFAIL for every query.
Why the Recommended Range Is 14 to 28 Days
RFC 1912 recommends an Expire value between 1,209,600 and 2,419,200 seconds. That's 14 to 28 days. RIPE-203, the European equivalent guidance document, suggests the upper bound of 28 days as well.
The reasoning is practical. Two weeks gives a real operations team time to actually fix a serious primary server outage, including over weekends, holidays, and the inevitable situations where the on-call person is unreachable. Four weeks is the outer boundary of what's reasonable before the data starts becoming a liability rather than an asset.
Set it lower than 14 days and you're gambling that your team can restore a primary server faster than that. Possible, but if your primary goes down on a Friday before a long weekend, a 7-day expire might not be enough. Plesk ships with a default expire of 604800 seconds, which is 7 days, and that's exactly why this warning shows up so often on Plesk-hosted domains. The platform's default is simply out of spec.
⇒ A concrete case: your primary nameserver goes down on Thursday afternoon. Your team gets the alert, starts investigating, and by Friday evening they've determined it needs a full rebuild. The engineer who owns the DNS infrastructure is traveling. The backup person has access but not full context. Nobody touches it over the weekend. Monday morning the right people are back, the rebuild starts, and by Tuesday afternoon ns1 is back online and zone transfers resume.
That's five days. Comfortable inside a 14-day expire window, but already past a 4-day expire if someone had set it that low. And this assumes no procurement delays, no waiting on a vendor, no data center access issues. Real outages at real companies have stretched two and three weeks before the primary was fully restored. The 14-day minimum exists precisely because "we'll have it fixed in a few hours" is what every team says at the start of every serious outage.
Set it higher than 28 days and you're telling secondary servers to keep serving data that could be a month old without verification. That starts looking less like resilience and more like a stale data problem waiting to happen.
The Serial Number Warning Is Often a Companion Issue
If DNS Spy also flagged "SOA Serial Number Format Is Invalid" on the same domain, these two warnings are related and worth addressing together.
The serial number is how your secondary nameservers decide whether to initiate a zone transfer. The logic is simple: if the serial on the primary is higher than what the secondary has, the secondary pulls a fresh copy. If it's the same or lower, the secondary assumes nothing has changed.
The widely accepted format is date-based: YYYYMMDDNN, where NN is a two-digit counter for the number of changes made on that date. So the first update on May 8, 2026 would be 2026050801. Second update that same day would be 2026050802.
This format isn't technically required by DNS spec. Technically, the serial number just needs to be a valid 32-bit unsigned integer between 1 and 4,294,967,295. But the date-based format has become the de facto standard because it gives you a human-readable audit trail inside the record itself. When you're debugging a zone transfer issue at 2am, being able to see "the zone was last updated on April 28th" from the serial number alone is genuinely useful.
The serial number breaks in a few specific ways:
Going backwards. If you set the serial to a lower number than what secondaries already have, they will never pull an update. They'll keep serving their cached copy indefinitely, even when records change on the primary. This is the most common and most silently damaging serial number mistake.
Exceeding the 32-bit limit. The maximum value is 4,294,967,295. Some older control panels that auto-increment sequentially (starting from 1) can eventually roll past this ceiling. When that happens, zone transfers stop working and the error is often non-obvious.
Invalid format. Some control panels generate serial numbers that don't conform to any of the standard formats, including random strings or formats with punctuation. Secondary servers can't parse these correctly.
If you've rolled your serial to a number that secondaries already exceed, you can't simply increment your way out. The standard BIND recovery is to add 2,147,483,647 to your current primary serial, reload the zone, wait for all secondaries to sync to that value, then reset to your target serial and reload again.
The reason this works is that RFC 1982 defines serial comparison such that a serial is considered greater than another if the difference between them is less than 2^31. By jumping exactly 2,147,483,647 positions forward, you land within the "greater than" window as seen by every secondary, which triggers the zone transfer.
Once they've all caught up, you can set your intended serial and everything stays in sync. The undefined zone in RFC 1982 is a difference of exactly 2^31 between two serials, where comparison is neither greater nor less.
You don't want to land there, and this procedure keeps you clear of it.
How to Check Your Current SOA Values
Before changing anything, verify what you actually have.
SOA Record Field Reference: Recommended Values
Field | What It Controls | Recommended Value | What Goes Wrong If You Don't |
|---|---|---|---|
Serial | Zone version number. Secondaries compare this to decide whether to pull an update. | YYYYMMDDNN format. Increment on every change. | Secondaries stop syncing. Records change on primary, nobody finds out. |
Refresh | How often secondaries poll the primary for updates. | 3,600 to 86,400 seconds (1 to 24 hours) | Too low: unnecessary zone transfer traffic. Too high: slow propagation of legitimate record changes. |
Retry | How long a secondary waits before retrying a failed refresh attempt. | 900 seconds (15 minutes). Must be lower than Refresh. | Too high: long gaps between retry attempts during an outage, burning your expire clock faster than necessary. |
Expire | How long a secondary keeps serving your zone if it loses contact with the primary entirely. | 1,209,600 to 2,419,200 seconds (14 to 28 days) per RFC 1912 and RIPE-203. | Too low: secondary stops serving your zone before your team can restore the primary. Too high: stale records serve for weeks without verification. |
Minimum TTL | How long resolvers cache a negative response (record not found) for your zone. | 300 to 3,600 seconds (5 minutes to 1 hour) | Too high: newly added records are invisible to resolvers that cached a negative response. 86,400 (one day) is a common bad default. |
To check your current values:
dig SOA example.com +shortThis gives you all six fields in order. The output will look something like:
ns1.example.com. admin.example.com. 2024042801 3600 900 604800 300The expire value is the sixth number: 604800 here, which is 7 days, and would trigger the warning.
You can also check this against a specific nameserver to compare what primaries and secondaries are serving:
dig SOA example.com @ns1.example.com +short
dig SOA example.com @ns2.example.com +shortIf the serial numbers differ between nameservers, your zone transfers aren't working correctly.
How to Fix It
The change itself is straightforward. What you need to do depends on how your DNS is hosted.
If you're managing your own BIND zone files, find the SOA record in your zone file and update the Expire field to a value between 1,209,600 and 2,419,200. Increment the serial number at the same time. Then reload the zone:
rndc reload example.comIf you're using a managed DNS provider, this will be in the DNS settings panel. Every provider surfaces it differently. Look for "Zone Settings," "Advanced DNS," or "SOA Settings." Cloudflare, Route 53, and most other major providers manage the SOA automatically and won't let you edit these values directly. If that's your setup and you're still seeing this warning, the warning is likely coming from a third-party DNS health checker that has different thresholds than what your provider enforces, and you can likely ignore it.
If you're on Plesk, the default SOA template ships with a 7-day expire. Go to Tools & Settings, then DNS Templates, then SOA Records Templates, and update the Expire value to 1,209,600. After saving, apply the template to existing domains. Note that serial numbers may not match immediately across nameservers. That's normal. Give the zone transfer cycle time to run.
After making the change, verify it propagated:
dig SOA example.com +shortThe expire value should now reflect your update.
What DNS Spy Flags and Why
DNS Spy's scanner checks your SOA record as part of the zone integrity scan. The SOA expire warning appears when the Expire value falls below 1,209,600 seconds or exceeds 2,419,200 seconds. The serial number warning appears when the serial falls outside the valid unsigned 32-bit integer range of 1 to 4,294,967,295, or when the value is inconsistent across nameservers in a way that indicates zone transfers have stopped working.
These aren't show-stopping security vulnerabilities, but they're meaningful signals. An out-of-spec expire value tells you that either the zone was configured by someone who didn't know the recommendation, migrated from a platform with bad defaults, or hasn't been reviewed in a long time. Any of those is worth knowing.
The deeper value is in tracking changes over time. If your SOA serial suddenly drops, that's a sign something went wrong with your zone management, possibly a misconfigured control panel or a restore from backup that overwrote a newer serial with an older one. If your expire value changes without you making a deliberate decision to change it, that's worth looking at.
Run a full DNS health scan on your domains at dnsspy.io. The scanner checks SOA values, CNAME chains, dangling records, WHOIS expiration, and a set of other zone-level issues that tend to go unnoticed until they cause actual problems.