{"record":{"id":"f7b46f9dd8aad3e0","repo":"TechnitiumSoftware/DnsServer","slug":"old-and-new-record-types-do-not-match-f7b46f","errorCode":null,"errorMessage":"Old and new record types do not match.","messagePattern":"Old and new record types do not match\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":2756,"sourceCode":"        }\n\n        public override void UpdateRecord(DnsResourceRecord oldRecord, DnsResourceRecord newRecord)\n        {\n            switch (oldRecord.Type)\n            {\n                case DnsResourceRecordType.SOA:\n                    throw new InvalidOperationException(\"Cannot update record: use SetRecords() for \" + oldRecord.Type.ToString() + \" record\");\n\n                case DnsResourceRecordType.DNSKEY:\n                case DnsResourceRecordType.RRSIG:\n                case DnsResourceRecordType.NSEC:\n                case DnsResourceRecordType.NSEC3PARAM:\n                case DnsResourceRecordType.NSEC3:\n                    throw new InvalidOperationException(\"Cannot update DNSSEC records.\");\n\n                default:\n                    if (oldRecord.Type != newRecord.Type)\n                        throw new InvalidOperationException(\"Old and new record types do not match.\");\n\n                    if ((_dnssecStatus != AuthZoneDnssecStatus.Unsigned) && newRecord.GetAuthGenericRecordInfo().Disabled)\n                        throw new DnsServerException(\"Cannot update record: disabling records in a signed zones is not supported.\");\n\n                    if (newRecord.OriginalTtlValue > GetZoneSoaExpire())\n                        throw new DnsServerException(\"Cannot update record: TTL cannot be greater than SOA EXPIRE.\");\n\n                    if (!TryDeleteRecord(oldRecord.Type, oldRecord.RDATA, out DnsResourceRecord deletedRecord))\n                        throw new DnsServerException(\"Cannot update record: the record does not exists to be updated.\");\n\n                    AddRecord(newRecord, out IReadOnlyList<DnsResourceRecord> addedRecords, out IReadOnlyList<DnsResourceRecord> deletedRecords);\n\n                    List<DnsResourceRecord> allDeletedRecords = new List<DnsResourceRecord>(deletedRecords.Count + 1);\n                    allDeletedRecords.Add(deletedRecord);\n                    allDeletedRecords.AddRange(deletedRecords);\n\n                    CommitAndIncrementSerial(allDeletedRecords, addedRecords);\n","sourceCodeStart":2738,"sourceCodeEnd":2774,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L2738-L2774","documentation":"Thrown by PrimaryZone.UpdateRecord (default case) when oldRecord.Type != newRecord.Type. UpdateRecord only swaps the rdata of a single RR; it cannot change a record's type. This is a precondition check, surfaced as InvalidOperationException.","triggerScenarios":"Calling zone.UpdateRecord(oldRecord, newRecord) where the two records have different DnsResourceRecordType values.","commonSituations":"Editor code that builds newRecord from a form where the user changed the type field; copy-paste between update calls with mismatched type constants; refactoring rdata objects across types.","solutions":["Ensure newRecord is constructed with the same Type as oldRecord.","If the type really must change, do a Delete(oldType) + Add(newType) sequence instead.","Assert type equality before calling UpdateRecord in generic code."],"exampleFix":"// before\nzone.UpdateRecord(oldRecord, newRecord); // newRecord.Type differs\n\n// after\nif (oldRecord.Type != newRecord.Type)\n{\n    zone.DeleteRecord(oldRecord.Type, oldRecord.RDATA);\n    zone.AddRecord(newRecord);\n}\nelse\n    zone.UpdateRecord(oldRecord, newRecord);","handlingStrategy":"validation","validationCode":"if (oldRecord.Type != newRecord.Type)\n{\n    zone.DeleteRecord(oldRecord.Type, oldRecord.RDATA);\n    zone.AddRecord(newRecord);\n}\nelse\n    zone.UpdateRecord(oldRecord, newRecord);","typeGuard":"static bool TypesMatch(DnsResourceRecord a, DnsResourceRecord b) => a.Type == b.Type;","tryCatchPattern":"null","preventionTips":["Derive newRecord.Type from oldRecord.Type unless a type change is intended.","Assert type equality in update formatters before submit."],"tags":["dns","primary-zone","validation","update","precondition"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}