TechnitiumSoftware/DnsServer · error · DnsServerException
Cannot set record: TTL cannot be greater than SOA EXPIRE.
Error message
Cannot set record: TTL cannot be greater than SOA EXPIRE.
What it means
Thrown by PrimaryZone.SetRecords() in the SOA case when the new SOA record's TTL (OriginalTtlValue) is greater than the new SOA EXPIRE value. Per DNS semantics, a resolver could cache the record longer than the EXPIRE window in which secondary servers are guaranteed to have valid data, causing stale answers; the server enforces TTL <= EXPIRE.
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:2543
break;
}
}
switch (type)
{
case DnsResourceRecordType.CNAME:
case DnsResourceRecordType.DS:
throw new InvalidOperationException("Cannot set " + type.ToString() + " record at zone apex.");
case DnsResourceRecordType.SOA:
if ((records.Count != 1) || !records[0].Name.Equals(_name, StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException("Invalid SOA record.");
DnsResourceRecord newSoaRecord = records[0];
DnsSOARecordData newSoa = newSoaRecord.RDATA as DnsSOARecordData;
if (newSoaRecord.OriginalTtlValue > newSoa.Expire)
throw new DnsServerException("Cannot set record: TTL cannot be greater than SOA EXPIRE.");
if (newSoa.Retry > newSoa.Refresh)
throw new DnsServerException("Cannot set record: SOA RETRY cannot be greater than SOA REFRESH.");
if (newSoa.Refresh > newSoa.Expire)
throw new DnsServerException("Cannot set record: SOA REFRESH cannot be greater than SOA EXPIRE.");
//remove any record info except serial date scheme and comments
bool useSoaSerialDateScheme;
string comments;
{
SOARecordInfo recordInfo = newSoaRecord.GetAuthSOARecordInfo();
useSoaSerialDateScheme = recordInfo.UseSoaSerialDateScheme;
comments = recordInfo.Comments;
}
newSoaRecord.Tag = null; //remove old record infoView on GitHub (pinned to d0484b6c1e)
Solutions
- Set the SOA TTL to a value <= the SOA EXPIRE before calling SetRecords.
- If you need a long TTL, raise EXPIRE to at least that value first (subject to the REFRESH <= EXPIRE constraint).
- Validate OriginalTtlValue <= Expire on the constructed SOA before submission.
Example fix
// before
var soa = new DnsSOARecordData { Expire = 3600 };
zone.SetRecords(DnsResourceRecordType.SOA, new[] { BuildSoaRecord(ttl: 86400, soa) }); // throws
// after
var soa = new DnsSOARecordData { Expire = 86400 };
zone.SetRecords(DnsResourceRecordType.SOA, new[] { BuildSoaRecord(ttl: 3600, soa) }); Defensive patterns
Strategy: validation
Validate before calling
if (type == DnsResourceRecordType.SOA)
{
var soa = (DnsSOARecordData)records[0].RDATA;
if (records[0].OriginalTtlValue > soa.Expire)
throw new ArgumentException("SOA TTL must be <= SOA EXPIRE.");
}
zone.SetRecords(type, records); Type guard
static bool SoaTtlWithinExpire(DnsResourceRecord soaRecord)
{
var soa = (DnsSOARecordData)soaRecord.RDATA;
return soaRecord.OriginalTtlValue <= soa.Expire;
} Try / catch
try { zone.SetRecords(type, records); }
catch (DnsServerException ex) when (ex.Message == "Cannot set record: TTL cannot be greater than SOA EXPIRE.")
{ Log.Error("Lower the SOA TTL or raise SOA EXPIRE."); } Prevention
- Keep SOA TTL <= EXPIRE in templates.
- When lowering EXPIRE, re-check the SOA TTL.
- Validate all three SOA timer invariants together before submission.
When it happens
Trigger: Calling SetRecords with an SOA whose OriginalTtlValue > newSoa.Expire (e.g. TTL 86400 but EXPIRE 3600).
Common situations: Copying a high-TTL SOA from another zone into one with a short EXPIRE; lowering EXPIRE for faster failover without also lowering the SOA TTL; template values where TTL and EXPIRE were set independently and inconsistently.
Related errors
- Cannot set records: TTL cannot be greater than SOA EXPIRE.
- Cannot set record: SOA REFRESH cannot be greater than SOA EX
- Cannot add record: TTL cannot be greater than SOA EXPIRE.
- Cannot update record: TTL cannot be greater than SOA EXPIRE.
- Invalid SOA record.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/10132d6fbe189305.
Report an issue: GitHub.