{"record":{"id":"dc1cc08614abe6cf","repo":"TechnitiumSoftware/DnsServer","slug":"the-zone-must-be-signed","errorCode":null,"errorMessage":"The zone must be signed.","messagePattern":"The zone must be signed\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":1091,"sourceCode":"        }\n\n        public DnssecPrivateKey UpdatePrivateKey(ushort keyTag, ushort rolloverDays)\n        {\n            lock (_dnssecPrivateKeys)\n            {\n                if (!_dnssecPrivateKeys.TryGetValue(keyTag, out DnssecPrivateKey privateKey))\n                    throw new DnsServerException(\"Cannot update private key: no such private key was found.\");\n\n                privateKey.RolloverDays = rolloverDays;\n\n                return privateKey;\n            }\n        }\n\n        public void DeletePrivateKey(ushort keyTag)\n        {\n            if (_dnssecStatus == AuthZoneDnssecStatus.Unsigned)\n                throw new DnsServerException(\"The zone must be signed.\");\n\n            lock (_dnssecPrivateKeys)\n            {\n                if (!_dnssecPrivateKeys.TryGetValue(keyTag, out DnssecPrivateKey privateKey))\n                    throw new DnsServerException(\"Cannot delete private key: no such private key was found.\");\n\n                if (privateKey.State != DnssecPrivateKeyState.Generated)\n                    throw new DnsServerException(\"Cannot delete private key: only keys with Generated state can be deleted.\");\n\n                _dnssecPrivateKeys.Remove(keyTag);\n            }\n        }\n\n        public void PublishAllGeneratedKeys()\n        {\n            if (_dnssecStatus == AuthZoneDnssecStatus.Unsigned)\n                throw new DnsServerException(\"The zone must be signed.\");\n","sourceCodeStart":1073,"sourceCodeEnd":1109,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L1073-L1109","documentation":"Thrown by DeletePrivateKey when the zone's DNSSEC status is Unsigned. Deleting a private key is only meaningful on a signed zone; an unsigned zone has no key store to mutate.","triggerScenarios":"Calling DeletePrivateKey(keyTag) on a zone whose DnssecStatus is Unsigned.","commonSituations":"A cleanup routine that runs against all zones regardless of signing state, hitting a zone that was never signed or was unsigned via UnsignZone.","solutions":["Guard the call with a DnssecStatus != Unsigned check.","If the zone was unsigned, the keys are already gone; nothing to delete.","Restrict cleanup scripts to zones where DnssecStatus is SignedWithNSEC or SignedWithNSEC3."],"exampleFix":"// before\nzone.DeletePrivateKey(keyTag);\n\n// after\nif (zone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n    zone.DeletePrivateKey(keyTag);","handlingStrategy":"validation","validationCode":"// Only delete keys on a signed zone\nif (zone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n    zone.DeletePrivateKey(keyTag);","typeGuard":"static bool CanDeletePrivateKey(ApexZone zone) =>\n    zone.DnssecStatus != AuthZoneDnssecStatus.Unsigned;","tryCatchPattern":"try\n{\n    zone.DeletePrivateKey(keyTag);\n}\ncatch (DnsServerException ex) when (ex.Message == \"The zone must be signed.\")\n{\n    // nothing to delete on an unsigned zone\n}","preventionTips":["Filter cleanup scripts to signed zones only.","An unsigned zone holds no keys, so deletion is implicitly a no-op."],"tags":["dnssec","private-key","state-precondition","validation","csharp"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}