{"record":{"id":"49172a3fb54134c6","repo":"TechnitiumSoftware/DnsServer","slug":"old-and-new-record-types-do-not-match-49172a","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/PrimarySubDomainZone.cs","lineNumber":233,"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 ((_primaryZone.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 > _primaryZone.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 InvalidOperationException(\"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                    _primaryZone.CommitAndIncrementSerial(allDeletedRecords, addedRecords);\n","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimarySubDomainZone.cs#L215-L251","documentation":"Thrown by PrimarySubDomainZone.UpdateRecord when oldRecord.Type != newRecord.Type. UpdateRecord is a same-type replace (delete-old/add-new at the same RRset), so a type change is undefined; the guard rejects it with InvalidOperationException before any state mutation.","triggerScenarios":"zone.UpdateRecord(oldRecord, newRecord) where the two records differ in Type (e.g., old is A, new is AAAA).","commonSituations":"Mis-ordered arguments; 'migrating' a name from one record type to another via Update instead of delete+add; record-import pipelines that recompute type per row.","solutions":["Ensure old and new share the same Type before calling UpdateRecord.","For a genuine type change, delete the old record and add the new one as separate operations.","Validate the pairing in the caller so mismatched types never reach the API."],"exampleFix":"// before\nzone.UpdateRecord(oldARecord, newAaaaRecord);\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    throw new InvalidOperationException(\"Record types differ; delete + add instead.\");\nzone.UpdateRecord(oldRecord, newRecord);","typeGuard":"static bool SameRecordType(DnsResourceRecord a, DnsResourceRecord b) => a.Type == b.Type;","tryCatchPattern":null,"preventionTips":["Assert oldRecord.Type == newRecord.Type before UpdateRecord.","For type migrations, delete then add rather than update.","Pair records by (name, type) in import pipelines."],"tags":["csharp","dns","zone-management","validation","technitium-dns"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}