TechnitiumSoftware/DnsServer · error · DnsServerException

Failed to delete Cluster: only a Primary node can delete the

Error message

Failed to delete Cluster: only a Primary node can delete the Cluster.

What it means

Thrown by DeleteCluster when the current server's self node is not the Primary node. Only the Primary node holds authority to tear down the entire cluster because it owns the primary zone, the catalog zone, and the canonical node list. Secondary nodes are restricted from this destructive operation.

Source

Thrown at DnsServerCore/Cluster/ClusterManager.cs:675

            //update cluster catalog zone ACLs, TSIG key name and save zone file
            UpdateClusterCatalogZoneOptions(clusterCatalogZoneInfo);

            //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))

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Identify the Primary node (use GetPrimaryNode or inspect the cluster node list) and run DeleteCluster on that server.
  2. Check GetSelfNode().Type == ClusterNodeType.Primary before invoking DeleteCluster.

Example fix

// before
_dnsWebService.ClusterManager.DeleteCluster(false);
// after
if (_dnsWebService.ClusterManager.GetSelfNode().Type == ClusterNodeType.Primary)
    _dnsWebService.ClusterManager.DeleteCluster(false);
else
    throw new InvalidOperationException("Run this operation on the cluster Primary node.");
Defensive patterns

Strategy: validation

Validate before calling

if (_dnsWebService.ClusterManager.GetSelfNode().Type != ClusterNodeType.Primary)
    throw new InvalidOperationException("DeleteCluster must run on the Primary node.");
_dnsWebService.ClusterManager.DeleteCluster(false);

Type guard

static bool IsPrimaryNode(ClusterManager cm)
    => cm.ClusterInitialized && cm.GetSelfNode().Type == ClusterNodeType.Primary;

Try / catch

try
{
    _dnsWebService.ClusterManager.DeleteCluster(false);
}
catch (DnsServerException ex) when (ex.Message.Contains("only a Primary node can delete"))
{
    throw new InvalidOperationException("Redirect this request to the cluster Primary node.", ex);
}

Prevention

When it happens

Trigger: DeleteCluster is called from a server whose GetSelfNode().Type is ClusterNodeType.Secondary rather than Primary. The guard at line 674 fires after the ClusterInitialized check passes.

Common situations: Running the delete API call or CLI command on the wrong server in a multi-node cluster (a Secondary instead of the Primary); load-balanced API requests hitting a Secondary backend.

Related errors


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