{"record":{"id":"55375bc421be702a","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-ask-secondary-node-to-leave-the-specifi","errorCode":null,"errorMessage":"Failed to ask Secondary node to leave: the specified node does not exist in the Cluster.","messagePattern":"Failed to ask Secondary node to leave: the specified node does not exist in the Cluster\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":753,"sourceCode":"            TriggerNotifyAllSecondaryNodes();\n\n            //trigger NS and SOA update for member zones\n            TriggerRecordUpdateForClusterCatalogMemberZones();\n\n            return secondaryNode;\n        }\n\n        public async Task<ClusterNode> AskSecondaryNodeToLeaveClusterAsync(int secondaryNodeId)\n        {\n            if (!ClusterInitialized)\n                throw new DnsServerException(\"Failed to ask Secondary node to leave: the Cluster is not initialized.\");\n\n            if (GetSelfNode().Type != ClusterNodeType.Primary)\n                throw new DnsServerException(\"Failed to ask Secondary node to leave: only a Primary node can ask a Secondary node to leave the Cluster.\");\n\n            //find existing secondary node\n            if (!_clusterNodes.TryGetValue(secondaryNodeId, out ClusterNode secondaryNode))\n                throw new DnsServerException(\"Failed to ask Secondary node to leave: the specified node does not exist in the Cluster.\");\n\n            if (secondaryNode.Type == ClusterNodeType.Primary)\n                throw new DnsServerException(\"Failed to ask Secondary node to leave: the specified node is the Cluster Primary node and cannot be removed.\");\n\n            //ask secondary node to leave the cluster\n            await secondaryNode.AskSecondaryNodeToLeaveClusterAsync();\n\n            return secondaryNode;\n        }\n\n        public ClusterNode DeleteSecondaryNode(int secondaryNodeId)\n        {\n            if (!ClusterInitialized)\n                throw new DnsServerException(\"Failed to delete Secondary node: the Cluster is not initialized.\");\n\n            if (GetSelfNode().Type != ClusterNodeType.Primary)\n                throw new DnsServerException(\"Failed to delete Secondary node: only a Primary node can delete a Secondary node from the Cluster.\");\n","sourceCodeStart":735,"sourceCodeEnd":771,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L735-L771","documentation":"Thrown by AskSecondaryNodeToLeaveClusterAsync when the provided secondaryNodeId is not found in _clusterNodes. The TryGetValue at line 752 fails, meaning no node with that integer ID exists in the current cluster.","triggerScenarios":"AskSecondaryNodeToLeaveClusterAsync(secondaryNodeId) is called with an ID that does not match any key in the _clusterNodes dictionary. This happens when the ID is stale, wrong, or the node was already removed.","commonSituations":"Stale UI showing a node that was already deleted; client passing the wrong integer ID; race where the node was removed between the UI loading the list and the user clicking leave.","solutions":["Refresh the cluster node list and pass a currently-valid secondaryNodeId.","Verify _clusterNodes.ContainsKey(secondaryNodeId) before calling.","Handle the case where the node was already removed (treat as a no-op success)."],"exampleFix":"// before\nawait _clusterManager.AskSecondaryNodeToLeaveClusterAsync(nodeId);\n// after\nif (!_clusterManager.ClusterNodes.Any(n => n.Key == nodeId))\n    return; // node already gone — nothing to do\nawait _clusterManager.AskSecondaryNodeToLeaveClusterAsync(nodeId);","handlingStrategy":"validation","validationCode":"// Verify the node exists before asking it to leave\nif (!_dnsWebService.ClusterManager.ClusterNodes.Any(n => n.Key == nodeId))\n    return; // node already gone — nothing to do\nawait _dnsWebService.ClusterManager.AskSecondaryNodeToLeaveClusterAsync(nodeId);","typeGuard":"static bool NodeExists(ClusterManager cm, int nodeId)\n    => cm.ClusterNodes.Any(n => n.Key == nodeId);","tryCatchPattern":"try\n{\n    await _clusterManager.AskSecondaryNodeToLeaveClusterAsync(nodeId);\n}\ncatch (DnsServerException ex) when (ex.Message.Contains(\"does not exist in the Cluster\"))\n{\n    // node already removed — treat as idempotent success\n}","preventionTips":["Refresh the node list before presenting leave/delete options to the user.","Check ClusterNodes for the ID before calling.","Handle 'does not exist' as a no-op success in automation to be idempotent."],"tags":["cluster","leave","not-found","stale-reference"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}