TechnitiumSoftware/DnsServer · error · DnsServerException

Failed to update Primary node: the Cluster is not initialize

Error message

Failed to update Primary node: the Cluster is not initialized.

What it means

Thrown at the top of UpdatePrimaryNodeAsync when ClusterInitialized is false. Updating the primary node's URL/IP only makes sense inside an active cluster, so the method refuses on a standalone or already-disbanded server. Same precondition pattern as Leave/Promote.

Source

Thrown at DnsServerCore/Cluster/ClusterManager.cs:1513

            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)
            {
                try
                {
                    IReadOnlyList<IPAddress> ipAddresses = await DnsClient.ResolveIPAsync(_dnsWebService.DnsServer, primaryNodeUrl.Host, _dnsWebService.DnsServer.IPv6Mode, cancellationToken);
                    if (ipAddresses.Count < 1)
                        throw new DnsServerException($"The domain name '{primaryNodeUrl.Host}' does not have an A/AAAA record configured.");

                    primaryNodeIpAddresses = ipAddresses;
                }
                catch (Exception ex)
                {
                    throw new DnsServerException($"Failed to update Primary node: the Primary node domain name '{primaryNodeUrl.Host}' could not be resolved to an IP address.", ex);
                }
            }

            ClusterNode primaryNode;

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Gate the call: if (!clusterManager.ClusterInitialized) rejoin or report 'not clustered' instead of calling update.
  2. If clustered state was lost unexpectedly, restore the cluster config file or re-run JoinClusterAsync before updating.
  3. Add a UI/API guard so the update-primary action is disabled when not clustered.

Example fix

// before
await clusterManager.UpdatePrimaryNodeAsync(primaryUrl);

// after
if (!clusterManager.ClusterInitialized)
    return BadRequest("Server is not part of a cluster.");
await clusterManager.UpdatePrimaryNodeAsync(primaryUrl);
Defensive patterns

Strategy: validation

Validate before calling

if (!clusterManager.ClusterInitialized)
    return BadRequest("Not clustered.");
await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, ips, cancellationToken: ct);

Type guard

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

Try / catch

try { await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, ips, cancellationToken: ct); }
catch (DnsServerException ex) when (ex.Message.Contains("not initialized"))
{ /* not clustered — rejoin or report */ }

Prevention

When it happens

Trigger: Calling UpdatePrimaryNodeAsync (to change the primary's address or swap which node is primary) on a server with no cluster nodes loaded.

Common situations: Operator runs 'update primary' on a standalone box; cluster config was wiped but the UI still offered the action; the node had already left the cluster.

Related errors


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