{"record":{"id":"75cf59660ebaeccf","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-update-primary-node-the-cluster-is-not","errorCode":null,"errorMessage":"Failed to update Primary node: the Cluster is not initialized.","messagePattern":"Failed to update Primary node: the Cluster is not initialized\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":1513,"sourceCode":"            ClusterNode secondaryNode = GetSelfNode();\n\n            if (secondaryNode.Type != ClusterNodeType.Secondary)\n                throw new DnsServerException(\"Failed to leave Cluster: only Secondary nodes can leave the Cluster.\");\n\n            if (!forceLeave)\n            {\n                //delete self node from cluster on primary node\n                await primaryNode.DeleteSecondaryNodeAsync(secondaryNode);\n            }\n\n            //delete all cluster config\n            DeleteAllClusterConfig();\n        }\n\n        public async Task<ClusterNode> UpdatePrimaryNodeAsync(Uri primaryNodeUrl, IReadOnlyList<IPAddress> primaryNodeIpAddresses = null, int primaryNodeId = -1, CancellationToken cancellationToken = default)\n        {\n            if (!ClusterInitialized)\n                throw new DnsServerException(\"Failed to update Primary node: the Cluster is not initialized.\");\n\n            if (primaryNodeIpAddresses is null)\n            {\n                try\n                {\n                    IReadOnlyList<IPAddress> ipAddresses = await DnsClient.ResolveIPAsync(_dnsWebService.DnsServer, primaryNodeUrl.Host, _dnsWebService.DnsServer.IPv6Mode, cancellationToken);\n                    if (ipAddresses.Count < 1)\n                        throw new DnsServerException($\"The domain name '{primaryNodeUrl.Host}' does not have an A/AAAA record configured.\");\n\n                    primaryNodeIpAddresses = ipAddresses;\n                }\n                catch (Exception ex)\n                {\n                    throw new DnsServerException($\"Failed to update Primary node: the Primary node domain name '{primaryNodeUrl.Host}' could not be resolved to an IP address.\", ex);\n                }\n            }\n\n            ClusterNode primaryNode;","sourceCodeStart":1495,"sourceCodeEnd":1531,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L1495-L1531","documentation":"Thrown at the top of UpdatePrimaryNodeAsync when ClusterInitialized is false. Updating the primary node's URL/IP only makes sense inside an active cluster, so the method refuses on a standalone or already-disbanded server. Same precondition pattern as Leave/Promote.","triggerScenarios":"Calling UpdatePrimaryNodeAsync (to change the primary's address or swap which node is primary) on a server with no cluster nodes loaded.","commonSituations":"Operator runs 'update primary' on a standalone box; cluster config was wiped but the UI still offered the action; the node had already left the cluster.","solutions":["Gate the call: if (!clusterManager.ClusterInitialized) rejoin or report 'not clustered' instead of calling update.","If clustered state was lost unexpectedly, restore the cluster config file or re-run JoinClusterAsync before updating.","Add a UI/API guard so the update-primary action is disabled when not clustered."],"exampleFix":"// before\nawait clusterManager.UpdatePrimaryNodeAsync(primaryUrl);\n\n// after\nif (!clusterManager.ClusterInitialized)\n    return BadRequest(\"Server is not part of a cluster.\");\nawait clusterManager.UpdatePrimaryNodeAsync(primaryUrl);","handlingStrategy":"validation","validationCode":"if (!clusterManager.ClusterInitialized)\n    return BadRequest(\"Not clustered.\");\nawait clusterManager.UpdatePrimaryNodeAsync(primaryUrl, ips, cancellationToken: ct);","typeGuard":"static bool CanUpdatePrimary(ClusterManager cm) => cm.ClusterInitialized;","tryCatchPattern":"try { await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, ips, cancellationToken: ct); }\ncatch (DnsServerException ex) when (ex.Message.Contains(\"not initialized\"))\n{ /* not clustered — rejoin or report */ }","preventionTips":["Gate update-primary calls on ClusterInitialized.","Disable the update-primary action when the node is standalone.","After leaving a cluster, refresh UI state to remove cluster-only actions."],"tags":["cluster","precondition","update-primary","technitium","state-guard"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}