TechnitiumSoftware/DnsServer · error · InvalidOperationException
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 PrimarySubDomainZone.UpdateRecord when TryDeleteRecord(oldRecord.Type, oldRecord.RDATA) returns false — i.e., the exact old record is not present in the zone. UpdateRecord is a delete-then-add atomic pair, so the old record must exist verbatim. The guard raises InvalidOperationException ('does not exists' is a verbatim source typo) before adding the new record, leaving the zone unchanged.
Source
Thrown at DnsServerCore/Dns/Zones/PrimarySubDomainZone.cs:242
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 ((_primaryZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned) && newRecord.GetAuthGenericRecordInfo().Disabled)
throw new DnsServerException("Cannot update record: disabling records in a signed zones is not supported.");
if (newRecord.OriginalTtlValue > _primaryZone.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 InvalidOperationException("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);
_primaryZone.CommitAndIncrementSerial(allDeletedRecords, addedRecords);
if (_primaryZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)
_primaryZone.UpdateDnssecRecordsFor(this, oldRecord.Type);
_primaryZone.TriggerNotify();
break;
}
}
#endregionView on GitHub (pinned to d0484b6c1e)
Solutions
- Re-read the current record from the zone and use it as 'old' before updating.
- Use optimistic-concurrency: if the update fails with 'does not exist', reload and retry or report not-found.
- Ensure the old record's RDATA matches the stored record exactly (case, wire format).
Example fix
// before
zone.UpdateRecord(staleOld, newRecord); // throws if gone
// after
if (!zone.TryGetRecords(oldRecord.Type, out var current)
|| !current.Any(r => r.RDATA.SequenceEqual(oldRecord.RDATA)))
return; // record already gone; nothing to update
zone.UpdateRecord(oldRecord, newRecord); Defensive patterns
Strategy: validation
Validate before calling
if (!zone.TryGetRecords(oldRecord.Type, out var rrset)
|| !rrset.Any(r => r.RDATA.SequenceEqual(oldRecord.RDATA)))
return; // already gone
zone.UpdateRecord(oldRecord, newRecord); Type guard
static bool RecordExists(IReadOnlyList<DnsResourceRecord> rrset, DnsResourceRecord oldR) =>
rrset.Any(r => r.RDATA.SequenceEqual(oldR.RDATA)); Try / catch
try { zone.UpdateRecord(oldRecord, newRecord); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not exists"))
{ /* stale snapshot: reload and retry, or treat as no-op */ } Prevention
- Reload the old record immediately before UpdateRecord under contention.
- Compare records by full RDATA, not partial fields.
- Handle 'does not exist' as a recoverable optimistic-concurrency signal.
When it happens
Trigger: zone.UpdateRecord(old, new) where 'old' was already deleted, never existed, or whose RDATA does not byte-match the stored RRset.
Common situations: Stale 'old' snapshot read before a concurrent edit; race where another client deleted the record; comparing records by partial fields rather than full RDATA.
Related errors
- Cannot delete DNSSEC records.
- Cannot update record: use SetRecords() for {oldRecord.Type}
- Cannot update DNSSEC records.
- Old and new record types do not match.
- Cannot update record: disabling records in a signed zones is
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/bc8f862c7e67a1f1.
Report an issue: GitHub.