TechnitiumSoftware/DnsServer · error · DnsWebServiceException
Cannot update record: the old record does not exists.
Error message
Cannot update record: the old record does not exists.
What it means
Thrown by UpdateRecord in the default case branch (non-CNAME/DNAME/APP records) when oldRecord.Name differs from newRecord.Name AND authZone.DeleteRecord(oldRecord.Type, oldRecord.RDATA) returns false. This means the specific old record's RDATA could not be found for deletion during a name-move operation. Notably this throws DnsWebServiceException, not DnsServerException like the other UpdateRecord errors.
Source
Thrown at DnsServerCore/Dns/ZoneManagers/AuthZoneManager.cs:2357
newZone.SetRecords(newRecord.Type, new DnsResourceRecord[] { newRecord });
if (newZone is SubDomainZone subDomainZone1)
subDomainZone1.AutoUpdateState();
}
break;
default:
if (oldRecord.Name.Equals(newRecord.Name, StringComparison.OrdinalIgnoreCase))
{
authZone.UpdateRecord(oldRecord, newRecord);
if (authZone is SubDomainZone subDomainZone)
subDomainZone.AutoUpdateState();
}
else
{
if (!authZone.DeleteRecord(oldRecord.Type, oldRecord.RDATA))
throw new DnsWebServiceException("Cannot update record: the old record does not exists.");
if (authZone is SubDomainZone subDomainZone)
{
if (authZone.IsEmpty)
_root.TryRemove(oldRecord.Name, out SubDomainZone _); //remove empty sub zone
else
subDomainZone.AutoUpdateState();
}
AuthZone newZone = GetOrAddSubDomainZone(zoneName, newRecord.Name);
newZone.AddRecord(newRecord);
if (newZone is SubDomainZone subDomainZone1)
subDomainZone1.AutoUpdateState();
}
break;
}View on GitHub (pinned to d0484b6c1e)
Solutions
- Re-fetch the current record from the zone before constructing oldRecord to ensure RDATA matches exactly.
- Use a query to get the authoritative record, then pass that exact object as oldRecord.
- If concurrent edits are expected, implement optimistic locking or retry the fetch-update cycle.
Example fix
// before (oldRecord may have stale RDATA)
authZoneManager.UpdateRecord("example.com", staleOldRecord, newRecord);
// after (fetch fresh record first)
var currentRecords = authZoneManager.GetRecords("example.com", oldRecord.Name, oldRecord.Type);
if (currentRecords.Count == 0)
throw new InvalidOperationException("Old record not found; it may have been modified or deleted.");
authZoneManager.UpdateRecord("example.com", currentRecords[0], newRecord); Defensive patterns
Strategy: validation
Validate before calling
// fetch the current authoritative record before attempting a name-move update
var current = authZoneManager.GetRecords(zoneName, oldRecord.Name, oldRecord.Type);
if (current.Count == 0 || !current[0].RDATA.Equals(oldRecord.RDATA))
throw new InvalidOperationException("Old record RDATA does not match current zone state."); Type guard
static bool RecordRdataMatches(DnsResourceRecord stored, DnsResourceRecord candidate)
=> stored.Type == candidate.Type && stored.RDATA.Equals(candidate.RDATA); Try / catch
try
{
authZoneManager.UpdateRecord(zoneName, oldRecord, newRecord);
}
catch (DnsWebServiceException ex) when (ex.Message.Contains("the old record does not exists"))
{
// RDATA was stale; re-fetch and retry
var fresh = authZoneManager.GetRecords(zoneName, oldRecord.Name, oldRecord.Type);
if (fresh.Count > 0)
authZoneManager.UpdateRecord(zoneName, fresh[0], newRecord);
} Prevention
- Always fetch the current record from the zone before constructing oldRecord for a name-move update.
- Pass the exact DnsResourceRecord object returned by the zone query as oldRecord.
- Be aware this error uses DnsWebServiceException, not DnsServerException — catch accordingly.
When it happens
Trigger: Calling UpdateRecord where the old and new records have different names (moving a record to a new name), and the old record's exact RDATA does not match what is stored in the zone. The DeleteRecord(type, rdata) overload returns false when the RDATA doesn't match any stored record, triggering this exception.
Common situations: oldRecord was constructed from stale data and its RDATA no longer matches the zone's current record (e.g. TTL or RDATA content changed since the client fetched it); concurrent modification between fetch and update; RDATA comparison fails due to normalization differences (case in domain names within RDATA, whitespace).
Related errors
- Cannot update record: new record must be of same type.
- Cannot update record: use SetRecords() for updating SOA reco
- Cannot update record: zone '{zoneName}' does not exists.
- Failed to update Secondary node: the specified node does not
- The domain name '<domain>' does not belong to the zone: <zon
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/aa9dea3b8b87998f.
Report an issue: GitHub.