TechnitiumSoftware/DnsServer · error · DnsServerException

Failed to leave Cluster: the Cluster is not initialized.

Error message

Failed to leave Cluster: the Cluster is not initialized.

What it means

Thrown by LeaveClusterAsync at the top of the method when ClusterInitialized is false. ClusterInitialized is true only when _clusterNodes is non-null and contains at least one node, so this fires on a standalone server that has never joined (or has already fully left) a cluster. LeaveClusterAsync is meaningless without cluster state, so it aborts immediately.

Source

Thrown at DnsServerCore/Cluster/ClusterManager.cs:1488

                _dnsWebService.AuthManager.SaveConfigFile();
                SaveConfigFile();
            }
            finally
            {
                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

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Check ClusterManager.ClusterInitialized before calling LeaveClusterAsync and treat false as already-left.
  2. If you expected to be clustered, inspect the cluster config file / _clusterNodes to see why state was cleared and rejoin if needed.
  3. Make leave idempotent in the caller: guard with a pre-check so repeated clicks do not throw.

Example fix

// before
await clusterManager.LeaveClusterAsync(force: false);

// after
if (clusterManager.ClusterInitialized)
    await clusterManager.LeaveClusterAsync(force: false);
Defensive patterns

Strategy: validation

Validate before calling

if (!clusterManager.ClusterInitialized)
    return; // already standalone; nothing to leave
await clusterManager.LeaveClusterAsync(force: false);

Type guard

static bool IsClustered(ClusterManager cm) => cm.ClusterInitialized;

Try / catch

try { await clusterManager.LeaveClusterAsync(force: false); }
catch (DnsServerException ex) when (ex.Message.Contains("not initialized"))
{ /* already not clustered; treat as success */ }

Prevention

When it happens

Trigger: Invoking LeaveClusterAsync on a server where _clusterNodes is null or empty: a node that never joined, a node that already called LeaveClusterAsync/LeaveClusterAsync(true), or a node whose cluster config was deleted out-of-band.

Common situations: UI/API call to 'leave cluster' on a primary-only standalone server; re-running a leave after it already succeeded; a race where DeleteAllClusterConfig ran (e.g. on error cleanup) before the user clicked leave.

Related errors


AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13). Data as JSON: /api/errors/908b07908b643b2e. Report an issue: GitHub.