{"record":{"id":"6c98db08ef797735","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-delete-dnssec-records-6c98db","errorCode":null,"errorMessage":"Cannot delete DNSSEC records.","messagePattern":"Cannot delete DNSSEC records\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":2690,"sourceCode":"                    }\n\n                    return false;\n            }\n        }\n\n        public override bool DeleteRecords(DnsResourceRecordType type)\n        {\n            switch (type)\n            {\n                case DnsResourceRecordType.SOA:\n                    throw new InvalidOperationException(\"Cannot delete SOA 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 delete DNSSEC records.\");\n\n                default:\n                    if (_entries.TryRemove(type, out IReadOnlyList<DnsResourceRecord> removedRecords))\n                    {\n                        CommitAndIncrementSerial(removedRecords);\n\n                        if (_dnssecStatus != AuthZoneDnssecStatus.Unsigned)\n                            UpdateDnssecRecordsFor(this, type);\n\n                        TriggerNotify();\n\n                        return true;\n                    }\n\n                    return false;\n            }\n        }\n","sourceCodeStart":2672,"sourceCodeEnd":2708,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L2672-L2708","documentation":"Thrown by PrimaryZone.DeleteRecords when the requested type is one of the DNSSEC record types (DNSKEY, RRSIG, NSEC, NSEC3PARAM, NSEC). DNSSEC records are managed internally by the signing engine (UpdateDnssecRecordsFor), so manual deletion is rejected as a programming error.","triggerScenarios":"Calling zone.DeleteRecords(type) where type is DNSKEY, RRSIG, NSEC, NSEC3PARAM, or NSEC3 on a PrimaryZone.","commonSituations":"Generic delete-all loops that sweep every type; tooling that treats DNSSEC records like normal RRs; switching a zone out of signed mode and trying to strip records by hand.","solutions":["Filter DNSSEC types (DNSKEY, RRSIG, NSEC, NSEC3PARAM, NSEC3) out before calling DeleteRecords.","To remove DNSSEC data, change the zone's DNSSEC status / re-sign rather than deleting individual RRs.","Maintain an IsDnssecType(type) helper and guard all bulk operations with it."],"exampleFix":"// before\nforeach (var type in allTypes)\n    zone.DeleteRecords(type);\n\n// after\nvar dnssec = new[]{ DnsResourceRecordType.DNSKEY, DnsResourceRecordType.RRSIG,\n    DnsResourceRecordType.NSEC, DnsResourceRecordType.NSEC3PARAM, DnsResourceRecordType.NSEC3 };\nforeach (var type in allTypes.Except(dnssec).Append(SOA-blacklist))\n    zone.DeleteRecords(type);","handlingStrategy":"type-guard","validationCode":"static readonly HashSet<DnsResourceRecordType> DnssecTypes = new()\n{\n    DnsResourceRecordType.DNSKEY, DnsResourceRecordType.RRSIG,\n    DnsResourceRecordType.NSEC, DnsResourceRecordType.NSEC3PARAM,\n    DnsResourceRecordType.NSEC3\n};\nforeach (var type in types.Where(t => !DnssecTypes.Contains(t) && t != DnsResourceRecordType.SOA))\n    zone.DeleteRecords(type);","typeGuard":"static bool IsDnssecType(DnsResourceRecordType t) =>\n    t == DnsResourceRecordType.DNSKEY || t == DnsResourceRecordType.RRSIG ||\n    t == DnsResourceRecordType.NSEC || t == DnsResourceRecordType.NSEC3PARAM ||\n    t == DnsResourceRecordType.NSEC3;","tryCatchPattern":"null","preventionTips":["Centralize IsDnssecType() and reuse it across add/delete/update guards.","Drive DNSSEC record lifecycle only through the signing engine, never manual deletes.","When changing zone signed status, expect the engine to rewrite DNSSEC RRs."],"tags":["dns","primary-zone","dnssec","immutable-record","delete"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}