TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to add Secondary node: the Secondary node domain name
Error message
Failed to add Secondary node: the Secondary node domain name must be a subdomain of the Cluster domain name.
What it means
Thrown by JoinCluster when the Secondary node's URL host does not end with '.' + the cluster domain. This ensures every Secondary's DNS Server Domain Name is a proper subdomain of the cluster domain so that NS/A/AAAA records can be placed correctly within the cluster primary zone.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:694
if (!forceDelete && (_clusterNodes.Count > 1))
throw new DnsServerException("Failed to delete Cluster: please remove all Secondary nodes before deleting the Cluster.");
DeleteAllClusterConfig();
}
public ClusterNode JoinCluster(int secondaryNodeId, Uri secondaryNodeUrl, IReadOnlyList<IPAddress> secondaryNodeIpAddresses, X509Certificate2 secondaryNodeCertificate)
{
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))View on GitHub (pinned to d0484b6c1e)
Solutions
- Set the Secondary server's DNS Server Domain Name to a subdomain of the cluster domain (e.g., 'ns2.cluster.example.com' for cluster domain 'cluster.example.com') before joining.
- Re-issue the join request with a corrected secondaryNodeUrl whose Host ends with '.{clusterDomain}'.
Example fix
// before
var nodeUrl = new Uri("https://ns2.other.com:5380/");
_clusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert);
// after — secondary domain must be a subdomain of the cluster domain
var nodeUrl = new Uri("https://ns2.cluster.example.com:5380/");
_clusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert); Defensive patterns
Strategy: validation
Validate before calling
string clusterDomain = _dnsWebService.ClusterManager.ClusterDomain;
string secondaryHost = secondaryNodeUrl.Host.ToLowerInvariant();
if (!secondaryHost.EndsWith("." + clusterDomain, StringComparison.OrdinalIgnoreCase))
throw new InvalidOperationException($"Secondary domain '{secondaryHost}' must be a subdomain of '{clusterDomain}'.");
_dnsWebService.ClusterManager.JoinCluster(nodeId, secondaryNodeUrl, nodeIps, cert); Type guard
static bool IsValidSecondaryDomain(Uri secondaryUrl, string clusterDomain)
=> secondaryUrl.Host.ToLowerInvariant().EndsWith("." + clusterDomain, StringComparison.OrdinalIgnoreCase); Try / catch
try
{
_dnsWebService.ClusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert);
}
catch (DnsServerException ex) when (ex.Message.Contains("must be a subdomain of the Cluster domain"))
{
throw new InvalidOperationException($"Set the Secondary's DNS Server Domain Name to a subdomain of the cluster domain and retry.", ex);
} Prevention
- Configure the Secondary server's DNS Server Domain Name to include the cluster domain suffix before joining.
- Validate the URL host against the cluster domain in your orchestration script before calling JoinCluster.
- Document the subdomain naming convention for all cluster nodes.
When it happens
Trigger: JoinCluster is called with a secondaryNodeUrl whose Host property (lowercased) does not satisfy secondaryNodeDomain.EndsWith('.' + _clusterDomain). For example, joining 'ns2.other.com' to a cluster domain of 'cluster.example.com'.
Common situations: The Secondary server's DNS Server Domain Name was not set to include the cluster domain suffix before the join attempt; copy-paste error in the URL; using an IP-based or unrelated hostname URL.
Related errors
- Failed to add Secondary node: A node with the same DNS Serve
- Failed to add Secondary node: the Cluster is not initialized
- Failed to add Secondary node: only a Primary node can add a
- Failed to add Secondary node: node ID already exists in the
- Failed to add Secondary node: a maximum of 255 nodes are sup
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/b9ba9a8aa8ebc921.
Report an issue: GitHub.