TechnitiumSoftware/DnsServer · error · DnsServerException

Failed to add Secondary node: A node with the same DNS Serve

Error message

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.

What it means

Thrown by JoinCluster when an existing cluster node already has the same DNS Server Domain Name (host) as the new Secondary being added. Node names must be unique so NS and address records do not collide in the cluster primary zone.

Source

Thrown at DnsServerCore/Cluster/ClusterManager.cs:702

        {
            if (!ClusterInitialized)
                throw new DnsServerException("Failed to add Secondary node: the Cluster is not initialized.");

            if (GetSelfNode().Type != ClusterNodeType.Primary)
                throw new DnsServerException("Failed to add Secondary node: only a Primary node can add a Secondary node to the Cluster.");

            string secondaryNodeDomain = secondaryNodeUrl.Host.ToLowerInvariant();

            if (!secondaryNodeDomain.EndsWith("." + _clusterDomain, StringComparison.OrdinalIgnoreCase))
                throw new DnsServerException("Failed to add Secondary node: the Secondary node domain name must be a subdomain of the Cluster domain name.");

            IReadOnlyDictionary<int, ClusterNode> existingClusterNodes = _clusterNodes;

            //validate for duplicate names
            foreach (KeyValuePair<int, ClusterNode> existingClusterNode in existingClusterNodes)
            {
                if (existingClusterNode.Value.Name.Equals(secondaryNodeUrl.Host, StringComparison.OrdinalIgnoreCase))
                    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.");
            }

            //add secondary node to cluster nodes
            ClusterNode secondaryNode = new ClusterNode(this, secondaryNodeId, secondaryNodeUrl, secondaryNodeIpAddresses, ClusterNodeType.Secondary, ClusterNodeState.Unknown);
            Dictionary<int, ClusterNode> updatedClusterNodes = new Dictionary<int, ClusterNode>(existingClusterNodes.Count + 1);

            foreach (KeyValuePair<int, ClusterNode> existingClusterNode in existingClusterNodes)
                updatedClusterNodes[existingClusterNode.Value.Id] = existingClusterNode.Value;

            if (!updatedClusterNodes.TryAdd(secondaryNode.Id, secondaryNode))
                throw new DnsServerException("Failed to add Secondary node: node ID already exists in the Cluster. Please try again.");

            if (updatedClusterNodes.Count > 255)
                throw new DnsServerException("Failed to add Secondary node: a maximum of 255 nodes are supported by the Cluster.");

            IReadOnlyDictionary<int, ClusterNode> originalValue = Interlocked.CompareExchange(ref _clusterNodes, updatedClusterNodes, existingClusterNodes);
            if (!ReferenceEquals(originalValue, existingClusterNodes))
                throw new DnsServerException("Failed to add Secondary node: please try again.");

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Delete the existing node with the duplicate name first using DeleteSecondaryNode, then retry the join.
  2. Change the new Secondary's DNS Server Domain Name to something unique before joining.

Example fix

// before
_clusterManager.JoinCluster(nodeId, new Uri("https://ns2.cluster.example.com:5380/"), ips, cert);
// after — remove the stale duplicate first
if (_clusterManager.TryGetClusterNode("ns2.cluster.example.com", out var existing))
    _clusterManager.DeleteSecondaryNode(existing.Id);
_clusterManager.JoinCluster(nodeId, new Uri("https://ns2.cluster.example.com:5380/"), ips, cert);
Defensive patterns

Strategy: validation

Validate before calling

// Check for an existing node with the same hostname before joining
if (_dnsWebService.ClusterManager.TryGetClusterNode(secondaryNodeUrl.Host, out var existing))
    throw new InvalidOperationException($"Node '{existing.Name}' already exists; delete it or change the Secondary's domain name.");
_dnsWebService.ClusterManager.JoinCluster(nodeId, secondaryNodeUrl, nodeIps, cert);

Type guard

static bool IsSecondaryNameUnique(ClusterManager cm, Uri secondaryUrl)
    => !cm.TryGetClusterNode(secondaryUrl.Host, out _);

Try / catch

try
{
    _dnsWebService.ClusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert);
}
catch (DnsServerException ex) when (ex.Message.Contains("same DNS Server Domain Name already exists"))
{
    // delete the stale node first, or change the Secondary's domain name, then retry
    throw;
}

Prevention

When it happens

Trigger: JoinCluster iterates existingClusterNodes and finds existingClusterNode.Value.Name.Equals(secondaryNodeUrl.Host, OrdinalIgnoreCase) is true for some existing node. This happens when the Secondary's hostname matches a node already in _clusterNodes.

Common situations: Re-adding a Secondary node that was asked to leave but not yet deleted from the node list; two Secondary servers configured with the same DNS Server Domain Name; retrying a join after a partial failure that already registered the name.

Related errors


AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13). Data as JSON: /api/errors/69b64cff588e028d. Report an issue: GitHub.