{"record":{"id":"7de762dcf1edeb8f","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-update-primary-node-the-primary-node-s","errorCode":null,"errorMessage":"Failed to update Primary node: the Primary node's domain name already exists in the Cluster. Please try again after changing the Primary DNS Server's domain name.","messagePattern":"Failed to update Primary node: the Primary node's domain name already exists in the Cluster\\. Please try again after changing the Primary DNS Server's domain name\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":1578,"sourceCode":"\n                //update cluster nodes\n                _clusterNodes = updatedClusterNodes;\n\n                //promote secondary node to primary immediately\n                primaryNode.PromoteToPrimaryNode();\n\n                //ensure to save changes\n                SaveConfigFile();\n            }\n\n            //validate for duplicate names\n            foreach (KeyValuePair<int, ClusterNode> clusterNode in _clusterNodes)\n            {\n                if (clusterNode.Key == primaryNode.Id)\n                    continue; //skip self\n\n                if (clusterNode.Value.Name.Equals(primaryNodeUrl.Host, StringComparison.OrdinalIgnoreCase))\n                    throw new DnsServerException(\"Failed to update Primary node: the Primary node's domain name already exists in the Cluster. Please try again after changing the Primary DNS Server's domain name.\");\n            }\n\n            //get cluster secondary catalog zone\n            string clusterCatalogDomain = \"cluster-catalog.\" + _clusterDomain;\n\n            AuthZoneInfo clusterSecondaryCatalogZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(clusterCatalogDomain);\n            if (clusterSecondaryCatalogZoneInfo is null)\n                throw new DnsServerException($\"Failed to update Primary node: the Cluster Secondary Catalog zone '{clusterCatalogDomain}' does not exists.\");\n\n            //update primary node\n            primaryNode.UpdateNode(primaryNodeUrl, primaryNodeIpAddresses);\n\n            //update cluster catalog zone's primary name server\n            clusterSecondaryCatalogZoneInfo.PrimaryNameServerAddresses = primaryNodeIpAddresses.Convert(delegate (IPAddress ipAddress) { return new NameServerAddress(primaryNodeUrl.Host, ipAddress); });\n\n            //save all changes\n            _dnsWebService.DnsServer.AuthZoneManager.SaveZoneFile(clusterSecondaryCatalogZoneInfo.Name);\n            SaveConfigFile();","sourceCodeStart":1560,"sourceCodeEnd":1596,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L1560-L1596","documentation":"Thrown by UpdatePrimaryNodeAsync during the duplicate-name validation loop: another cluster node (not the one being updated) already has a Name equal (case-insensitive) to primaryNodeUrl.Host. DNS cluster node names must be unique because they map to DNS records and certificate identities.","triggerScenarios":"Calling UpdatePrimaryNodeAsync with a primaryUrl.Host that collides with an existing cluster node's Name (any node except the one being updated).","commonSituations":"Reusing a hostname already assigned to a secondary; a node was renamed but the old name lingered; two nodes restored from the same backup; wildcard/alias confusion where Host parses to a shared domain.","solutions":["Change the primary DNS server's hostname/domain name to a unique value before updating.","Rename or remove the conflicting cluster node so the name is free.","Validate primaryUrl.Host against all ClusterNodes.Values[].Name (case-insensitive) before submitting."],"exampleFix":"// before\nawait clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: id);\n\n// after\nstring host = primaryUrl.Host;\nbool dup = clusterManager.ClusterNodes\n    .Where(kv => kv.Key != id)\n    .Any(kv => kv.Value.Name.Equals(host, StringComparison.OrdinalIgnoreCase));\nif (dup) return Conflict($\"Node name '{host}' already in use.\");\nawait clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: id);","handlingStrategy":"validation","validationCode":"string host = primaryUrl.Host;\nbool duplicate = clusterManager.ClusterNodes\n    .Where(kv => kv.Key != primaryNodeId)\n    .Any(kv => kv.Value.Name.Equals(host, StringComparison.OrdinalIgnoreCase));\nif (duplicate)\n    return Conflict($\"Node name '{host}' already used by another cluster node.\");\nawait clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: primaryNodeId);","typeGuard":"static bool IsNodeNameUnique(ClusterManager cm, string host, int excludeId)\n    => cm.ClusterNodes.Where(kv => kv.Key != excludeId)\n         .All(kv => !kv.Value.Name.Equals(host, StringComparison.OrdinalIgnoreCase));","tryCatchPattern":"try { await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: id); }\ncatch (DnsServerException ex) when (ex.Message.Contains(\"domain name already exists\"))\n{ /* rename the primary DNS server to a unique hostname and retry */ }","preventionTips":["Give every cluster node a unique hostname from the start.","Validate primaryUrl.Host against existing node names before updating.","After renaming a node, propagate the rename cluster-wide before reusing old names."],"tags":["cluster","validation","duplicate","naming","update-primary","technitium"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}