{"record":{"id":"bef62b45c9c5e110","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-add-secondary-node-a-maximum-of-255-nod","errorCode":null,"errorMessage":"Failed to add Secondary node: a maximum of 255 nodes are supported by the Cluster.","messagePattern":"Failed to add Secondary node: a maximum of 255 nodes are supported by the Cluster\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":716,"sourceCode":"            //validate for duplicate names\n            foreach (KeyValuePair<int, ClusterNode> existingClusterNode in existingClusterNodes)\n            {\n                if (existingClusterNode.Value.Name.Equals(secondaryNodeUrl.Host, StringComparison.OrdinalIgnoreCase))\n                    throw new DnsServerException(\"Failed to add Secondary node: A node with the same DNS Server Domain Name already exists in the Cluster. Please try again after changing the Secondary node's DNS Server Domain Name.\");\n            }\n\n            //add secondary node to cluster nodes\n            ClusterNode secondaryNode = new ClusterNode(this, secondaryNodeId, secondaryNodeUrl, secondaryNodeIpAddresses, ClusterNodeType.Secondary, ClusterNodeState.Unknown);\n            Dictionary<int, ClusterNode> updatedClusterNodes = new Dictionary<int, ClusterNode>(existingClusterNodes.Count + 1);\n\n            foreach (KeyValuePair<int, ClusterNode> existingClusterNode in existingClusterNodes)\n                updatedClusterNodes[existingClusterNode.Value.Id] = existingClusterNode.Value;\n\n            if (!updatedClusterNodes.TryAdd(secondaryNode.Id, secondaryNode))\n                throw new DnsServerException(\"Failed to add Secondary node: node ID already exists in the Cluster. Please try again.\");\n\n            if (updatedClusterNodes.Count > 255)\n                throw new DnsServerException(\"Failed to add Secondary node: a maximum of 255 nodes are supported by the Cluster.\");\n\n            IReadOnlyDictionary<int, ClusterNode> originalValue = Interlocked.CompareExchange(ref _clusterNodes, updatedClusterNodes, existingClusterNodes);\n            if (!ReferenceEquals(originalValue, existingClusterNodes))\n                throw new DnsServerException(\"Failed to add Secondary node: please try again.\");\n\n            secondaryNode.InitializeHeartbeatTimer();\n\n            //update cluster zone and save zone file\n            FindExistingRecordTtlValues(out uint nsTtl, out uint aTtl); //find existing record TTL values\n            AddClusterPrimaryZoneRecordsFor(secondaryNode, nsTtl, aTtl, secondaryNodeCertificate);\n\n            //update cluster catalog zone ACLs and save zone file\n            UpdateClusterCatalogZoneOptions();\n\n            //save all changes\n            SaveConfigFile();\n\n            //notify all secondary nodes","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L698-L734","documentation":"Thrown by JoinCluster when adding the new node would bring the total node count above 255. The cluster uses byte-sized node identifiers and zone-record structures that cap at 255 members, so this is a hard architectural limit enforced after the TryAdd succeeds but before the CompareExchange commits.","triggerScenarios":"JoinCluster adds a node to updatedClusterNodes and then checks updatedClusterNodes.Count > 255 at line 715. If the existing cluster already has 255 nodes, the 256th triggers this error.","commonSituations":"Large-scale deployment attempting to exceed the documented 255-node ceiling; automated scaling script that does not track the node count.","solutions":["Remove unused or offline Secondary nodes (via DeleteSecondaryNode) before adding new ones to stay within 255.","Redesign the DNS topology so no single cluster exceeds 255 nodes (split into multiple clusters or reduce redundancy)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const int MAX_CLUSTER_NODES = 255;\nif (_dnsWebService.ClusterManager.ClusterNodes.Count >= MAX_CLUSTER_NODES)\n    throw new InvalidOperationException($\"Cluster is at the {MAX_CLUSTER_NODES}-node limit; remove a Secondary before adding another.\");\n_dnsWebService.ClusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert);","typeGuard":"static bool HasClusterCapacity(ClusterManager cm, int max = 255)\n    => cm.ClusterNodes.Count < max;","tryCatchPattern":"try\n{\n    _clusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert);\n}\ncatch (DnsServerException ex) when (ex.Message.Contains(\"maximum of 255 nodes\"))\n{\n    throw new InvalidOperationException(\"Cluster node limit reached. Remove unused Secondaries or split into multiple clusters.\", ex);\n}","preventionTips":["Monitor cluster node count and alert before approaching 255.","Remove offline or unused Secondary nodes before adding new ones.","Plan cluster topology to stay within the 255-node architectural limit."],"tags":["cluster","join","capacity-limit","scaling"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}