{"record":{"id":"454a81d64d504663","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-delete-dnssec-records","errorCode":null,"errorMessage":"Cannot delete DNSSEC records.","messagePattern":"Cannot delete DNSSEC records\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimarySubDomainZone.cs","lineNumber":170,"sourceCode":"                        _primaryZone.TriggerNotify();\n\n                        return true;\n                    }\n\n                    return false;\n            }\n        }\n\n        public override bool DeleteRecords(DnsResourceRecordType type)\n        {\n            switch (type)\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                        _primaryZone.CommitAndIncrementSerial(removedRecords);\n\n                        if (_primaryZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n                            _primaryZone.UpdateDnssecRecordsFor(this, type);\n\n                        _primaryZone.TriggerNotify();\n\n                        return true;\n                    }\n\n                    return false;\n            }\n        }\n","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimarySubDomainZone.cs#L152-L188","documentation":"Thrown by PrimarySubDomainZone.DeleteRecords(DnsResourceRecordType type) when 'type' is one of the DNSSEC-managed record types (DNSKEY, RRSIG, NSEC, NSEC3PARAM, NSEC3). DNSSEC records are generated and maintained by the zone-signing machinery, so direct bulk deletion would corrupt the signature chain. The guard raises InvalidOperationException before touching the _entries store.","triggerScenarios":"Calling zone.DeleteRecords(DnsResourceRecordType.RRSIG) (or DNSKEY/NSEC/NSEC3PARAM/NSEC3) on a PrimarySubDomainZone.","commonSituations":"Attempting to 'clean up' DNSSEC records manually after disabling DNSSEC; generic delete-all loops that iterate every record type including DNSSEC types; tooling that treats RRSIG as normal records.","solutions":["Call _primaryZone.UnsignZone() to remove all DNSSEC records through the supported path.","Filter the type list to exclude DNSSEC types before calling DeleteRecords.","Do not manage DNSSEC RRs by hand; let the DNSSEC engine add/remove them."],"exampleFix":"// before\nzone.DeleteRecords(DnsResourceRecordType.RRSIG);\n\n// after — remove DNSSEC the supported way\nif (primaryZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n    primaryZone.UnsignZone();","handlingStrategy":"validation","validationCode":"if (IsDnssecRecordType(type)) throw new InvalidOperationException(\"Cannot delete DNSSEC via DeleteRecords; use UnsignZone.\");\nzone.DeleteRecords(type);","typeGuard":"static bool IsDnssecRecordType(DnsResourceRecordType t) =>\n    t == DnsResourceRecordType.DNSKEY || t == DnsResourceRecordType.RRSIG ||\n    t == DnsResourceRecordType.NSEC || t == DnsResourceRecordType.NSEC3PARAM ||\n    t == DnsResourceRecordType.NSEC3;","tryCatchPattern":null,"preventionTips":["Never call DeleteRecords with a DNSSEC type; use UnsignZone for full removal.","In bulk delete loops, skip DNSSEC types via a shared guard.","Centralize the IsDnssecRecordType check so every delete path uses it."],"tags":["csharp","dns","dnssec","zone-management","validation","technitium-dns"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}