TechnitiumSoftware/DnsServer · error · DnsServerException

Cannot update record: new record must be of same type.

Error message

Cannot update record: new record must be of same type.

What it means

Thrown by UpdateRecord when oldRecord.Type does not equal newRecord.Type. DNS record updates must preserve the resource record type (e.g. A stays A, CNAME stays CNAME). Changing the type is not an update; it requires a delete + add or using SetRecords.

Source

Thrown at DnsServerCore/Dns/ZoneManagers/AuthZoneManager.cs:2305

            if (authZone.AddRecord(record))
            {
                if (authZone is SubDomainZone subDomainZone)
                    subDomainZone.AutoUpdateState();

                return true;
            }

            return false;
        }

        public void UpdateRecord(string zoneName, DnsResourceRecord oldRecord, DnsResourceRecord newRecord)
        {
            ValidateIfDomainBelongsToZone(zoneName, oldRecord.Name);
            ValidateIfDomainBelongsToZone(zoneName, newRecord.Name);

            if (oldRecord.Type != newRecord.Type)
                throw new DnsServerException("Cannot update record: new record must be of same type.");

            if (oldRecord.Type == DnsResourceRecordType.SOA)
                throw new DnsServerException("Cannot update record: use SetRecords() for updating SOA record.");

            if (!_root.TryGet(zoneName, oldRecord.Name, out AuthZone authZone))
                throw new DnsServerException("Cannot update record: zone '" + zoneName + "' does not exists.");

            switch (oldRecord.Type)
            {
                case DnsResourceRecordType.CNAME:
                case DnsResourceRecordType.DNAME:
                case DnsResourceRecordType.APP:
                    if (oldRecord.Name.Equals(newRecord.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        authZone.SetRecords(newRecord.Type, new DnsResourceRecord[] { newRecord });

                        if (authZone is SubDomainZone subDomainZone)
                            subDomainZone.AutoUpdateState();

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Ensure oldRecord.Type == newRecord.Type before calling UpdateRecord; if the type must change, call DeleteRecord then AddRecord instead.
  2. Add a client-side guard in the UI to prevent type changes in edit mode.
  3. For bulk type changes, iterate with delete+add pairs rather than UpdateRecord.

Example fix

// before (fails: changing A to AAAA)
var oldRec = new DnsResourceRecord("host.example.com", DnsResourceRecordType.A, DnsClass.IN, 300, new DnsARecordData(IPAddress.Parse("10.0.0.1")));
var newRec = new DnsResourceRecord("host.example.com", DnsResourceRecordType.AAAA, DnsClass.IN, 300, new DnsAAAARecordData(IPAddress.Parse("fd00::1")));
authZoneManager.UpdateRecord("example.com", oldRec, newRec);

// after (delete + add for type change)
authZoneManager.DeleteRecord("example.com", oldRec);
authZoneManager.AddRecord("example.com", newRec);
Defensive patterns

Strategy: validation

Validate before calling

if (oldRecord.Type != newRecord.Type)
    throw new ArgumentException("Record type cannot be changed via UpdateRecord; use DeleteRecord + AddRecord instead.");

Type guard

static bool IsSameRecordType(DnsResourceRecord oldRecord, DnsResourceRecord newRecord)
    => oldRecord.Type == newRecord.Type;

Try / catch

try
{
    authZoneManager.UpdateRecord(zoneName, oldRecord, newRecord);
}
catch (DnsServerException ex) when (ex.Message.Contains("new record must be of same type"))
{
    // type changed: delete old + add new
    authZoneManager.DeleteRecord(zoneName, oldRecord);
    authZoneManager.AddRecord(zoneName, newRecord);
}

Prevention

When it happens

Trigger: Calling UpdateRecord(zoneName, oldRecord, newRecord) where oldRecord.Type != newRecord.Type. For example, passing an A record as oldRecord and an AAAA record as newRecord. The check fires after ValidateIfDomainBelongsToZone but before zone lookup, so domain validation passes first.

Common situations: Client UI that lets the user change the record type in an edit form without deleting and re-adding; API integration that constructs oldRecord and newRecord from different sources; migration script that changes record types in-place; copy-paste error in test data.

Related errors


AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13). Data as JSON: /api/errors/e6998d188c1ffcef. Report an issue: GitHub.