TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to leave Cluster: a Primary self node cannot leave th
Error message
Failed to leave Cluster: a Primary self node cannot leave the Cluster.
What it means
Thrown by LeaveClusterAsync when the primary node resolved by GetPrimaryNode() has State == ClusterNodeState.Self, i.e. this server is itself the cluster primary. A primary node cannot 'leave' its own cluster because leaving implies deregistering from a remote primary; the primary must instead transfer/demote. The guard stops an operator from orphaning the cluster.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:1493
try
{
//logout from primary node
await primaryNodeApiClient.LogoutAsync(cancellationToken);
}
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)
{View on GitHub (pinned to d0484b6c1e)
Solutions
- Promote a secondary to primary first (PromoteToPrimaryNodeAsync on a secondary, or transfer primary), then leave from the now-secondary node.
- If you intend to dissolve the cluster entirely, delete all cluster config / disband from the primary instead of calling leave.
- In shared automation, branch on node type: only secondaries call LeaveClusterAsync.
Example fix
// before: same leave path for every node
await clusterManager.LeaveClusterAsync(force: false);
// after: only secondaries leave; primary must be demoted/transferred first
if (clusterManager.GetPrimaryNode().State == ClusterNodeState.Self)
throw new InvalidOperationException("Demote/transfer primary before leaving.");
await clusterManager.LeaveClusterAsync(force: false); Defensive patterns
Strategy: validation
Validate before calling
if (clusterManager.GetPrimaryNode().State == ClusterNodeState.Self)
throw new InvalidOperationException("Demote or transfer primary before leaving.");
await clusterManager.LeaveClusterAsync(force: false); Type guard
static bool IsSelfPrimary(ClusterManager cm)
=> cm.ClusterInitialized && cm.GetPrimaryNode().State == ClusterNodeState.Self; Try / catch
try { await clusterManager.LeaveClusterAsync(force: false); }
catch (DnsServerException ex) when (ex.Message.Contains("Primary self node cannot leave"))
{ /* instruct operator to promote a secondary first */ } Prevention
- Branch cluster runbooks on node role; only secondaries leave.
- Before leaving, verify GetPrimaryNode() is not the self node.
- For full cluster dissolution, use the primary-side disband path instead of leave.
When it happens
Trigger: Calling LeaveClusterAsync from the server that currently holds the Primary role (GetPrimaryNode().State == Self).
Common situations: Operator on the primary node clicks 'Leave Cluster'; automation script runs the same leave routine on every cluster member including the primary; failover left this node as primary but the runbook still calls leave.
Related errors
- Failed to leave Cluster: only Secondary nodes can leave the
- Failed to refresh configuration: only Secondary nodes can sy
- Failed to resync configuration: only Secondary nodes can syn
- Failed to ask Secondary node to leave: only a Primary node c
- Failed to ask Secondary node to leave: the specified node is
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/ad3dfedfcd345b90.
Report an issue: GitHub.