TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to add Secondary node: the Cluster is not initialized
Error message
Failed to add Secondary node: the Cluster is not initialized.
What it means
Thrown by JoinCluster when ClusterInitialized is false. JoinCluster adds a Secondary node to an existing cluster, which requires the cluster to already be set up with a Primary node, a primary zone, and a catalog zone. Without an initialized cluster there is nothing to join to.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:686
public void DeleteCluster(bool forceDelete)
{
if (!ClusterInitialized)
throw new DnsServerException("Failed to delete Cluster: the Cluster is not initialized.");
if (GetSelfNode().Type != ClusterNodeType.Primary)
throw new DnsServerException("Failed to delete Cluster: only a Primary node can delete the Cluster.");
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.");
}
View on GitHub (pinned to d0484b6c1e)
Solutions
- Initialize the cluster on the Primary node first via InitializeCluster, then call JoinCluster on that same Primary.
- Check ClusterManager.ClusterInitialized before calling JoinCluster.
- Verify the server's cluster config file loaded correctly on startup.
Example fix
// before
_dnsWebService.ClusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert);
// after
if (!_dnsWebService.ClusterManager.ClusterInitialized)
throw new InvalidOperationException("Initialize the cluster on the Primary node first.");
_dnsWebService.ClusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert); Defensive patterns
Strategy: validation
Validate before calling
if (!_dnsWebService.ClusterManager.ClusterInitialized)
throw new InvalidOperationException("Initialize the cluster on the Primary node before joining a Secondary.");
_dnsWebService.ClusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert); Type guard
static bool CanJoinCluster(ClusterManager cm) => cm.ClusterInitialized;
Try / catch
try
{
_dnsWebService.ClusterManager.JoinCluster(nodeId, nodeUrl, nodeIps, cert);
}
catch (DnsServerException ex) when (ex.Message.Contains("add Secondary node") && ex.Message.Contains("not initialized"))
{
throw new InvalidOperationException("The cluster is not initialized. Run InitializeCluster on the Primary first.", ex);
} Prevention
- Initialize the cluster on the Primary before attempting any JoinCluster calls.
- Check ClusterInitialized in your orchestration before issuing join requests.
- Verify the cluster config file loaded on startup if initialization is unexpectedly missing.
When it happens
Trigger: JoinCluster(secondaryNodeId, secondaryNodeUrl, ...) is called on a server where _clusterNodes is null or empty. The guard at line 685 fires before any Secondary-node logic runs.
Common situations: Calling JoinCluster on the wrong server (e.g., on a Secondary or a fresh server instead of the initialized Primary); the Primary's cluster config was lost or not loaded; calling join before initialize completed.
Related errors
- Failed to delete Cluster: the Cluster is not initialized.
- Failed to ask Secondary node to leave: the Cluster is not in
- Failed to delete Secondary node: the Cluster is not initiali
- Failed to join Cluster: the Primary Node URL must use the do
- Failed to join Cluster: the Primary node does not have a Clu
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/eb962071da94477a.
Report an issue: GitHub.