TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to delete Cluster: please remove all Secondary nodes
Error message
Failed to delete Cluster: please remove all Secondary nodes before deleting the Cluster.
What it means
Thrown by DeleteCluster when forceDelete is false and more than one node exists in the cluster (_clusterNodes.Count > 1). This safety guard prevents orphaning Secondary nodes that would lose their Primary and be left in an inconsistent state. The Primary node alone counts as 1, so any Secondary pushes the count above the threshold.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:678
//finalize
_dnsWebService.DnsServer.ServerDomain = selfPrimaryNode.Name;
//save all changes
_dnsWebService.DnsServer.SaveConfigFile(true);
_dnsWebService.AuthManager.SaveConfigFile(true);
SaveConfigFile();
}
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;View on GitHub (pinned to d0484b6c1e)
Solutions
- Remove all Secondary nodes first using DeleteSecondaryNode or AskSecondaryNodeToLeaveClusterAsync, then call DeleteCluster(false).
- If you intentionally want to force teardown with Secondaries still present, call DeleteCluster(true) to bypass the guard.
Example fix
// before
_dnsWebService.ClusterManager.DeleteCluster(false);
// after — drain secondaries first
foreach (var node in _dnsWebService.ClusterManager.ClusterNodes)
{
if (node.Value.Type == ClusterNodeType.Secondary)
_dnsWebService.ClusterManager.DeleteSecondaryNode(node.Key);
}
_dnsWebService.ClusterManager.DeleteCluster(false); Defensive patterns
Strategy: validation
Validate before calling
// Drain all secondaries before deleting, or force-delete
foreach (var node in _dnsWebService.ClusterManager.ClusterNodes)
{
if (node.Value.Type == ClusterNodeType.Secondary)
_dnsWebService.ClusterManager.DeleteSecondaryNode(node.Key);
}
_dnsWebService.ClusterManager.DeleteCluster(false);
// or: _dnsWebService.ClusterManager.DeleteCluster(true); // force Type guard
static bool IsClusterDrained(ClusterManager cm)
=> cm.ClusterNodes.Count(n => n.Value.Type == ClusterNodeType.Secondary) == 0; Try / catch
try
{
_dnsWebService.ClusterManager.DeleteCluster(false);
}
catch (DnsServerException ex) when (ex.Message.Contains("remove all Secondary nodes"))
{
// either drain secondaries and retry, or call DeleteCluster(true) to force
throw;
} Prevention
- Always drain Secondary nodes before cluster teardown unless force-delete is intentional.
- Build a teardown script that removes secondaries in a loop, then deletes the cluster.
- Document the forceDelete flag clearly so operators know the trade-off.
When it happens
Trigger: DeleteCluster(false) is called when _clusterNodes contains the Primary plus one or more Secondary nodes. The guard at line 677 fires after the ClusterInitialized and Primary-node checks pass.
Common situations: Attempting a cluster teardown without first draining Secondary nodes; a scripted cleanup that skips the node-removal step.
Related errors
- Failed to delete Cluster: the Cluster is not initialized.
- Failed to delete Cluster: only a Primary node can delete the
- At least one parameter must be provided.
- DNS Server Cluster config file format is invalid.
- DNS Server Cluster config version not supported.
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/f9710f98a1c18faa.
Report an issue: GitHub.