TechnitiumSoftware/DnsServer · error · DnsServerException
Cannot update record: the record does not exists to be updat
Error message
Cannot update record: the record does not exists to be updated.
What it means
Thrown by PrimaryZone.UpdateRecord (default case) when TryDeleteRecord(oldRecord.Type, oldRecord.RDATA, ...) returns false, meaning the exact old record is not present. UpdateRecord performs a delete-then-add; if the old record is absent it cannot proceed. DnsServerException marks it as a state/data error.
Source
Thrown at DnsServerCore/Dns/Zones/PrimaryZone.cs:2765
case DnsResourceRecordType.DNSKEY:
case DnsResourceRecordType.RRSIG:
case DnsResourceRecordType.NSEC:
case DnsResourceRecordType.NSEC3PARAM:
case DnsResourceRecordType.NSEC3:
throw new InvalidOperationException("Cannot update DNSSEC records.");
default:
if (oldRecord.Type != newRecord.Type)
throw new InvalidOperationException("Old and new record types do not match.");
if ((_dnssecStatus != AuthZoneDnssecStatus.Unsigned) && newRecord.GetAuthGenericRecordInfo().Disabled)
throw new DnsServerException("Cannot update record: disabling records in a signed zones is not supported.");
if (newRecord.OriginalTtlValue > GetZoneSoaExpire())
throw new DnsServerException("Cannot update record: TTL cannot be greater than SOA EXPIRE.");
if (!TryDeleteRecord(oldRecord.Type, oldRecord.RDATA, out DnsResourceRecord deletedRecord))
throw new DnsServerException("Cannot update record: the record does not exists to be updated.");
AddRecord(newRecord, out IReadOnlyList<DnsResourceRecord> addedRecords, out IReadOnlyList<DnsResourceRecord> deletedRecords);
List<DnsResourceRecord> allDeletedRecords = new List<DnsResourceRecord>(deletedRecords.Count + 1);
allDeletedRecords.Add(deletedRecord);
allDeletedRecords.AddRange(deletedRecords);
CommitAndIncrementSerial(allDeletedRecords, addedRecords);
if (_dnssecStatus != AuthZoneDnssecStatus.Unsigned)
UpdateDnssecRecordsFor(this, oldRecord.Type);
TriggerNotify();
break;
}
}
#endregionView on GitHub (pinned to d0484b6c1e)
Solutions
- Re-fetch the current record from the zone before calling UpdateRecord.
- Check existence first and Add instead of Update if the record is new.
- Handle concurrent edits with optimistic retry against fresh data.
Example fix
// before
zone.UpdateRecord(staleOldRecord, newRecord);
// after
var current = zone.GetRecords(type)?.FirstOrDefault(r => r.RDATA.Equals(staleOldRecord.RDATA));
if (current is null)
zone.AddRecord(newRecord);
else
zone.UpdateRecord(current, newRecord); Defensive patterns
Strategy: validation
Validate before calling
var current = zone.GetRecords(oldRecord.Type)?
.FirstOrDefault(r => r.RDATA.Equals(oldRecord.RDATA));
if (current is null)
zone.AddRecord(newRecord);
else
zone.UpdateRecord(current, newRecord); Type guard
static bool RecordExists(PrimaryZone zone, DnsResourceRecord r) =>
zone.GetRecords(r.Type)?.Any(x => x.RDATA.Equals(r.RDATA)) == true; Try / catch
try { zone.UpdateRecord(oldRecord, newRecord); }
catch (DnsServerException ex) when (ex.Message.Contains("does not exists"))
{ /* re-fetch and retry, or Add */ } Prevention
- Re-read the live record before updating under concurrency.
- Use optimistic retry against a freshly fetched oldRecord.
- Distinguish 'create' from 'update' at the call site.
When it happens
Trigger: Calling zone.UpdateRecord(oldRecord, newRecord) when oldRecord (by type+rdata) no longer exists in the zone, e.g. it was already modified, deleted, or never added.
Common situations: Concurrent updates where another writer changed the record first; stale oldRecord captured from a cached zone snapshot; retrying an update after a prior success.
Related errors
- Old and new record types do not match.
- Cannot update record: TTL cannot be greater than SOA EXPIRE.
- Valid range is from 1 to 4.
- No such primary zone was found: <zoneName>
- Cannot set records. Please try again.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/52860d970fa09d9e.
Report an issue: GitHub.