{"record":{"id":"89abd737ebfb3151","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-unsign-zone-the-is-zone-not-signed","errorCode":null,"errorMessage":"Cannot unsign zone: the is zone not signed.","messagePattern":"Cannot unsign zone: the is zone not signed\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/Zones/PrimaryZone.cs","lineNumber":660,"sourceCode":"                foreach (KeyValuePair<string, Dictionary<DnsResourceRecordType, List<DnsResourceRecord>>> deletedRecordGroup in deletedRecordGroups)\n                {\n                    AuthZone zone = _dnsServer.AuthZoneManager.GetAuthZone(_name, deletedRecordGroup.Key);\n\n                    foreach (KeyValuePair<DnsResourceRecordType, List<DnsResourceRecord>> deletedRecordEntry in deletedRecordGroup.Value)\n                    {\n                        foreach (DnsResourceRecord deletedRecord in deletedRecordEntry.Value)\n                            zone.AddRecord(deletedRecord, out _, out _);\n                    }\n                }\n\n                throw;\n            }\n        }\n\n        public void UnsignZone()\n        {\n            if (_dnssecStatus == AuthZoneDnssecStatus.Unsigned)\n                throw new DnsServerException(\"Cannot unsign zone: the is zone not signed.\");\n\n            List<DnsResourceRecord> deletedRecords = new List<DnsResourceRecord>();\n            IReadOnlyList<AuthZone> zones = _dnsServer.AuthZoneManager.GetApexZoneWithSubDomainZones(_name);\n\n            foreach (AuthZone zone in zones)\n            {\n                deletedRecords.AddRange(zone.RemoveAllDnssecRecords());\n\n                if (zone is SubDomainZone subDomainZone)\n                {\n                    if (zone.IsEmpty)\n                        _dnsServer.AuthZoneManager.RemoveSubDomainZone(zone.Name); //remove empty sub zone\n                    else\n                        subDomainZone.AutoUpdateState();\n                }\n            }\n\n            Timer dnssecTimer = _dnssecTimer;","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/Zones/PrimaryZone.cs#L642-L678","documentation":"Thrown by PrimaryZone.UnsignZone when _dnssecStatus == AuthZoneDnssecStatus.Unsigned — i.e., the zone is not signed, so there is nothing to unsign. The guard raises DnsServerException before gathering the apex/sub-domain zone list. (Message text 'the is zone not signed' is a verbatim source wording.)","triggerScenarios":"Calling zone.UnsignZone() on an already-unsigned primary zone; double-unsign after a previous call; unsign after a failed sign that rolled back to Unsigned.","commonSituations":"UI 'Unsign' pressed on a zone that was never signed; automation that unsigns defensively without checking state.","solutions":["Check zone.DnssecStatus != Unsigned before calling UnsignZone.","Treat 'already unsigned' as a no-op in the caller rather than an error.","Guard concurrent unsign operations to avoid racing into Unsigned state."],"exampleFix":"// before\nzone.UnsignZone(); // may throw if unsigned\n\n// after\nif (zone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n    zone.UnsignZone();","handlingStrategy":"try-catch","validationCode":"if (zone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n    zone.UnsignZone();","typeGuard":"static bool CanUnsign(AuthZone z) => z.DnssecStatus != AuthZoneDnssecStatus.Unsigned;","tryCatchPattern":"try { zone.UnsignZone(); }\ncatch (DnsServerException ex) when (ex.Message.Contains(\"not signed\"))\n{ /* already unsigned: treat as no-op */ }","preventionTips":["Check DnssecStatus != Unsigned before UnsignZone.","Treat already-unsigned as a no-op in automation.","Guard concurrent unsign to avoid state races."],"tags":["csharp","dns","dnssec","zone-management","concurrency","technitium-dns"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}