{"record":{"id":"14af588a801faa25","repo":"TechnitiumSoftware/DnsServer","slug":"cannot-convert-the-zone-currentzoneinfo-displayn-14af58","errorCode":null,"errorMessage":"Cannot convert the zone '<currentZoneInfo.DisplayName>' from <currentZoneInfo.TypeName> to <AuthZoneInfo.GetZoneTypeName(newType)> zone: converting the zone will cause lose of DNSSEC private keys.","messagePattern":"Cannot convert the zone '<currentZoneInfo\\.DisplayName>' from <currentZoneInfo\\.TypeName> to <AuthZoneInfo\\.GetZoneTypeName\\(newType\\)> zone: converting the zone will cause lose of DNSSEC private keys\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dns/ZoneManagers/AuthZoneManager.cs","lineNumber":1451,"sourceCode":"\n        public AuthZoneInfo ConvertZoneTypeTo(string zoneName, AuthZoneType newType)\n        {\n            AuthZoneInfo currentZoneInfo = GetAuthZoneInfo(zoneName);\n            if (currentZoneInfo is null)\n                throw new DnsServerException(\"No such zone was found: \" + (zoneName.Length == 0 ? \".\" : zoneName));\n\n            //validate conversion type\n            if (currentZoneInfo.Type == newType)\n                throw new DnsServerException(\"Cannot convert the zone '\" + currentZoneInfo.DisplayName + \"' from \" + currentZoneInfo.TypeName + \" to \" + AuthZoneInfo.GetZoneTypeName(newType) + \" zone: the zone is already of the same type.\");\n\n            switch (currentZoneInfo.Type)\n            {\n                case AuthZoneType.Primary:\n                    switch (newType)\n                    {\n                        case AuthZoneType.Forwarder:\n                            if (currentZoneInfo.ApexZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n                                throw new DnsServerException(\"Cannot convert the zone '\" + currentZoneInfo.DisplayName + \"' from \" + currentZoneInfo.TypeName + \" to \" + AuthZoneInfo.GetZoneTypeName(newType) + \" zone: converting the zone will cause lose of DNSSEC private keys.\");\n\n                            break;\n\n                        default:\n                            throw new DnsServerException(\"Cannot convert the zone '\" + currentZoneInfo.DisplayName + \"' from \" + currentZoneInfo.TypeName + \" to \" + AuthZoneInfo.GetZoneTypeName(newType) + \" zone: not supported.\");\n                    }\n\n                    break;\n\n                case AuthZoneType.Secondary:\n                case AuthZoneType.SecondaryForwarder:\n                case AuthZoneType.SecondaryCatalog:\n                    switch (newType)\n                    {\n                        case AuthZoneType.Primary:\n                        case AuthZoneType.Forwarder:\n                        case AuthZoneType.Catalog:\n                            break;","sourceCodeStart":1433,"sourceCodeEnd":1469,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dns/ZoneManagers/AuthZoneManager.cs#L1433-L1469","documentation":"Thrown by ConvertZoneTypeTo when converting a Primary zone to a Forwarder zone while the zone carries DNSSEC material (currentZoneInfo.ApexZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned). Converting to Forwarder would discard the zone's authoritative DNSSEC private keys and break chain-of-trust, so the library refuses unless the zone is unsigned.","triggerScenarios":"Calling ConvertZoneTypeTo(\"zone\", AuthZoneType.Forwarder) on a signed Primary zone (DnssecStatus is e.g. Signed orInProgress). The Primary->Forwarder branch at line 1449 checks DnssecStatus and throws at line 1451 when it is not Unsigned.","commonSituations":"Switching a DNSSEC-signed authoritative zone to forwarding without first unsigning it. Promoting then reverting a zone while keys are still loaded. Forgetting that automated DNSSEC signing was enabled on the zone.","solutions":["Call UnsignPrimaryZone(zoneName) first to remove DNSSEC material, then retry the conversion.","Keep the zone as Primary if you must retain DNSSEC; do not convert to Forwarder.","Back up DNSSEC private keys before unsigning if you may re-sign later.","Check currentZoneInfo.ApexZone.DnssecStatus and warn the user before attempting the convert."],"exampleFix":"// before\nmanager.ConvertZoneTypeTo(zoneName, AuthZoneType.Forwarder); // throws if signed\n\n// after\nvar info = manager.GetAuthZoneInfo(zoneName);\nif (info.ApexZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n    manager.UnsignPrimaryZone(zoneName);\nmanager.ConvertZoneTypeTo(zoneName, AuthZoneType.Forwarder);","handlingStrategy":"validation","validationCode":"var info = manager.GetAuthZoneInfo(zoneName);\nif (info.Type == AuthZoneType.Primary && newType == AuthZoneType.Forwarder && info.ApexZone.DnssecStatus != AuthZoneDnssecStatus.Unsigned)\n    manager.UnsignPrimaryZone(zoneName); // unsign first","typeGuard":null,"tryCatchPattern":"catch (DnsServerException ex) when (ex.Message.Contains(\"DNSSEC private keys\")) { manager.UnsignPrimaryZone(zoneName); manager.ConvertZoneTypeTo(zoneName, newType); }","preventionTips":["Unsign Primary zones before converting to Forwarder.","Back up DNSSEC keys before unsigning.","Surface DnssecStatus in the UI before allowing a convert."],"tags":["dns","zone-management","convert","dnssec","data-loss-prevention"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}