{"record":{"id":"6b44276a7fb45995","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-promote-to-primary-node-the-cluster-sec-6b4427","errorCode":null,"errorMessage":"Failed to promote to Primary node: the Cluster Secondary zone does not exist.","messagePattern":"Failed to promote to Primary node: the Cluster Secondary zone does not exist\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":1955,"sourceCode":"        public async Task PromoteToPrimaryNodeAsync(bool forceDeletePrimary)\n        {\n            if (!ClusterInitialized)\n                throw new DnsServerException(\"Failed to promote to Primary node: the Cluster is not initialized.\");\n\n            //do validation\n            ClusterNode selfNewPrimaryNode = GetSelfNode();\n            if (selfNewPrimaryNode.Type != ClusterNodeType.Secondary)\n                throw new DnsServerException(\"Failed to promote to Primary node: only Secondary nodes can be promoted to Primary nodes.\");\n\n            string clusterCatalogDomain = \"cluster-catalog.\" + _clusterDomain;\n\n            AuthZoneInfo clusterCatalogZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(clusterCatalogDomain);\n            if (clusterCatalogZoneInfo is null)\n                throw new DnsServerException(\"Failed to promote to Primary node: the Cluster Secondary Catalog zone does not exist.\");\n\n            AuthZoneInfo clusterZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(_clusterDomain);\n            if (clusterZoneInfo is null)\n                throw new DnsServerException(\"Failed to promote to Primary node: the Cluster Secondary zone does not exist.\");\n\n            //stop cluster config refresh timer\n            StopConfigRefreshTimer();\n\n            //resync config and delete current primary node from the cluster immediately\n            ClusterNode existingPrimaryNode = GetPrimaryNode();\n\n            if (!forceDeletePrimary)\n            {\n                //resync complete config from current primary node to ensure all data is synced\n                _configLastSynced = DateTime.UnixEpoch; //to ensure complete config resync\n                await existingPrimaryNode.SyncConfigAsync();\n\n                //delete current cluster primary node\n                await existingPrimaryNode.DeleteClusterAsync(true);\n            }\n\n            //dispose primary node immediately to stop heartbeat","sourceCodeStart":1937,"sourceCodeEnd":1973,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L1937-L1973","documentation":"Thrown by PromoteToPrimaryNodeAsync when GetAuthZoneInfo(_clusterDomain) (the cluster's main secondary zone, distinct from the catalog zone) returns null. Promotion later converts this secondary zone into the cluster's primary zone, so it must pre-exist; absence indicates inconsistent cluster zone state.","triggerScenarios":"Promoting a secondary whose main '<clusterDomain>' secondary zone is missing (deleted/renamed/never created), even though the catalog zone may exist.","commonSituations":"Manual deletion of the cluster zone; partial cleanup from a failed join or prior promotion; zone file lost from disk; cluster domain mismatch.","solutions":["Re-establish the cluster zone by leaving (force) and rejoining to rebuild secondary zone state.","Restore the cluster zone file from backup.","Confirm _clusterDomain matches the actual zone name on disk."],"exampleFix":"// before\nawait clusterManager.PromoteToPrimaryNodeAsync(forceDeletePrimary: false);\n\n// after\nif (dnsServer.AuthZoneManager.GetAuthZoneInfo(clusterManager.ClusterDomain) is null)\n{\n    await clusterManager.LeaveClusterAsync(force: true);\n    await clusterManager.JoinClusterAsync(primaryUrl, creds, ct);\n}\nawait clusterManager.PromoteToPrimaryNodeAsync(forceDeletePrimary: false);","handlingStrategy":"validation","validationCode":"if (dnsServer.AuthZoneManager.GetAuthZoneInfo(clusterManager.ClusterDomain) is null)\n    throw new InvalidOperationException($\"Missing cluster zone '{clusterManager.ClusterDomain}'; rebuild cluster.\");\nawait clusterManager.PromoteToPrimaryNodeAsync(forceDeletePrimary: false);","typeGuard":"static bool ClusterZoneExists(DnsWebService svc, string clusterDomain)\n    => svc.DnsServer.AuthZoneManager.GetAuthZoneInfo(clusterDomain) is not null;","tryCatchPattern":"try { await clusterManager.PromoteToPrimaryNodeAsync(false); }\ncatch (DnsServerException ex) when (ex.Message.Contains(\"Cluster Secondary zone does not exist\"))\n{\n    await clusterManager.LeaveClusterAsync(force: true);\n    await clusterManager.JoinClusterAsync(primaryUrl, creds, ct);\n}","preventionTips":["Do not manually delete the main '<clusterDomain>' zone on a clustered node.","Confirm _clusterDomain matches the on-disk zone name.","Validate cluster zone presence before any promote attempt."],"tags":["cluster","dns-zone","promote","missing-state","technitium"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}