TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to leave Cluster: only Secondary nodes can leave the
Error message
Failed to leave Cluster: only Secondary nodes can leave the Cluster.
What it means
Thrown by LeaveClusterAsync when GetSelfNode().Type is not ClusterNodeType.Secondary. Only Secondary nodes are permitted to leave a cluster; a Primary node must be demoted or transferred (see error 182) and Unknown-typed nodes are not valid leavers. The check runs after the primary-self check, so it typically catches a node whose type is Unknown or was already promoted.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:1498
catch
{ }
}
}
public async Task LeaveClusterAsync(bool forceLeave)
{
if (!ClusterInitialized)
throw new DnsServerException("Failed to leave Cluster: the Cluster is not initialized.");
ClusterNode primaryNode = GetPrimaryNode();
if (primaryNode.State == ClusterNodeState.Self)
throw new DnsServerException("Failed to leave Cluster: a Primary self node cannot leave the Cluster.");
ClusterNode secondaryNode = GetSelfNode();
if (secondaryNode.Type != ClusterNodeType.Secondary)
throw new DnsServerException("Failed to leave Cluster: only Secondary nodes can leave the Cluster.");
if (!forceLeave)
{
//delete self node from cluster on primary node
await primaryNode.DeleteSecondaryNodeAsync(secondaryNode);
}
//delete all cluster config
DeleteAllClusterConfig();
}
public async Task<ClusterNode> UpdatePrimaryNodeAsync(Uri primaryNodeUrl, IReadOnlyList<IPAddress> primaryNodeIpAddresses = null, int primaryNodeId = -1, CancellationToken cancellationToken = default)
{
if (!ClusterInitialized)
throw new DnsServerException("Failed to update Primary node: the Cluster is not initialized.");
if (primaryNodeIpAddresses is null)
{View on GitHub (pinned to d0484b6c1e)
Solutions
- Confirm this is actually a Secondary node; if it was promoted to Primary, follow the primary-removal path instead.
- Refresh cluster state (TriggerResyncForConfig / re-login to primary) so node type is current, then retry leave.
- As a last resort, force-leave (forceLeave=true) only if you understand it skips primary deregistration — but still ensure the node type is Secondary first.
Example fix
// before
await clusterManager.LeaveClusterAsync(force: false);
// after
var self = clusterManager.GetSelfNode();
if (self.Type != ClusterNodeType.Secondary)
throw new InvalidOperationException($"Cannot leave: this node is {self.Type}.");
await clusterManager.LeaveClusterAsync(force: false); Defensive patterns
Strategy: validation
Validate before calling
var self = clusterManager.GetSelfNode();
if (self.Type != ClusterNodeType.Secondary)
throw new InvalidOperationException($"Node is {self.Type}; only secondaries can leave.");
await clusterManager.LeaveClusterAsync(force: false); Type guard
static bool IsSecondary(ClusterManager cm)
=> cm.ClusterInitialized && cm.GetSelfNode().Type == ClusterNodeType.Secondary; Try / catch
try { await clusterManager.LeaveClusterAsync(force: false); }
catch (DnsServerException ex) when (ex.Message.Contains("only Secondary nodes can leave"))
{ /* node is primary or unknown; follow demote/transfer path */ } Prevention
- Check GetSelfNode().Type before offering 'leave' in the UI.
- Resync config if node type shows Unknown to refresh metadata.
- Avoid re-running leave after a promotion that changed this node's role.
When it happens
Trigger: Calling LeaveClusterAsync on a node whose self type is Primary (and not detected as Self-primary by the earlier check) or Unknown — e.g. the node was just promoted to primary in-flight, or its type metadata is corrupt/uninitialized.
Common situations: State transition race where the node was promoted to Primary after the ClusterInitialized check but before the type check; a half-applied config that left Type as Unknown; operator confusion about which node they are acting on.
Related errors
- Failed to leave Cluster: a Primary self node cannot leave th
- Failed to promote to Primary node: only Secondary nodes can
- Failed to leave Cluster: the Cluster is not initialized.
- Failed to update Primary node: the specified node is the sel
- Failed to refresh configuration: only Secondary nodes can sy
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/74a095611364756a.
Report an issue: GitHub.