{"record":{"id":"58c5785e566dca61","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-update-primary-node-the-specified-prima","errorCode":null,"errorMessage":"Failed to update Primary node: the specified Primary node ID does not exists in the Cluster.","messagePattern":"Failed to update Primary node: the specified Primary node ID does not exists in the Cluster\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":1536,"sourceCode":"                {\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;\n\n            if (primaryNodeId < 0)\n                primaryNode = GetPrimaryNode();\n            else if (!_clusterNodes.TryGetValue(primaryNodeId, out primaryNode))\n                throw new DnsServerException(\"Failed to update Primary node: the specified Primary node ID does not exists in the Cluster.\");\n\n            if (primaryNode.State == ClusterNodeState.Self)\n                throw new DnsServerException(\"Failed to update Primary node: the specified node is the self node and cannot be updated this way.\");\n\n            if (primaryNode.Type == ClusterNodeType.Secondary)\n            {\n                //secondary node was promoted to primary node\n                ClusterNode formerPrimaryNode = GetPrimaryNode();\n\n                //dispose former primary node immediately to stop heartbeat\n                formerPrimaryNode.Dispose();\n\n                //remove former primary node from cluster nodes\n                IReadOnlyDictionary<int, ClusterNode> existingClusterNodes = _clusterNodes;\n                Dictionary<int, ClusterNode> updatedClusterNodes = new Dictionary<int, ClusterNode>(existingClusterNodes.Count - 1);\n\n                foreach (KeyValuePair<int, ClusterNode> existingClusterNode in existingClusterNodes)\n                {","sourceCodeStart":1518,"sourceCodeEnd":1554,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L1518-L1554","documentation":"Thrown by UpdatePrimaryNodeAsync when a non-negative primaryNodeId was supplied but no entry with that key exists in _clusterNodes (TryGetValue returned false). The method uses primaryNodeId < 0 as 'use the current primary', so any explicit ID must match an existing cluster node's Id.","triggerScenarios":"Calling UpdatePrimaryNodeAsync with a stale, wrong, or deleted primaryNodeId — e.g. an ID from a node that has since been removed, an ID copied from a different cluster, or a default/placeholder value that happened to be non-negative.","commonSituations":"UI passed a cached node ID after the cluster topology changed; client serialized the wrong numeric ID; a node was deleted between the UI list load and the update submit; off-by-one or type confusion passing a port/counter as the ID.","solutions":["Omit primaryNodeId (or pass -1) to target the current primary automatically.","Refresh the cluster node list and pass a currently-valid Id from clusterManager.ClusterNodes.","Validate the ID against ClusterNodes.Keys before calling the API."],"exampleFix":"// before\nawait clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: requestedId);\n\n// after\nif (requestedId >= 0 && !clusterManager.ClusterNodes.ContainsKey(requestedId))\n    return NotFound($\"Node {requestedId} not in cluster.\");\nawait clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: requestedId);","handlingStrategy":"validation","validationCode":"if (primaryNodeId >= 0 && !clusterManager.ClusterNodes.ContainsKey(primaryNodeId))\n    return NotFound($\"Node {primaryNodeId} is not in the cluster.\");\nawait clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: primaryNodeId);","typeGuard":"static bool IsValidNodeId(ClusterManager cm, int id) => id < 0 || cm.ClusterNodes.ContainsKey(id);","tryCatchPattern":"try { await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: id); }\ncatch (DnsServerException ex) when (ex.Message.Contains(\"ID does not exists\"))\n{ /* refresh node list and retry with a current id, or pass -1 */ }","preventionTips":["Pass -1 (or omit) when you mean 'the current primary'.","Refresh the cluster node list before submitting an explicit id.","Validate id against ClusterNodes.Keys at the API boundary."],"tags":["cluster","validation","update-primary","stale-reference","technitium"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}