TechnitiumSoftware/DnsServer · error · DnsServerException

Failed to update Secondary node: the specified node does not

Error message

Failed to update Secondary node: the specified node does not exist in the Cluster.

What it means

UpdateSecondaryNode looked up secondaryNodeId in the cluster node table and found nothing. The ID supplied does not correspond to any current cluster member.

Source

Thrown at DnsServerCore/Cluster/ClusterManager.cs:827

            //trigger NS and SOA update for member zones
            TriggerRecordUpdateForClusterCatalogMemberZones();

            return secondaryNode;
        }

        public ClusterNode UpdateSecondaryNode(int secondaryNodeId, Uri secondaryNodeUrl, IReadOnlyList<IPAddress> secondaryNodeIpAddresses, X509Certificate2 secondaryNodeCertificate)
        {
            if (!ClusterInitialized)
                throw new DnsServerException("Failed to update Secondary node: the Cluster is not initialized.");

            if (GetSelfNode().Type != ClusterNodeType.Primary)
                throw new DnsServerException("Failed to update Secondary node: only a Primary node can update a Secondary node's details in the Cluster.");

            IReadOnlyDictionary<int, ClusterNode> clusterNodes = _clusterNodes;

            if (!clusterNodes.TryGetValue(secondaryNodeId, out ClusterNode secondaryNode))
                throw new DnsServerException("Failed to update Secondary node: the specified node does not exist in the Cluster.");

            if (secondaryNode.Type != ClusterNodeType.Secondary)
                throw new DnsServerException("Failed to update Secondary node: the specified node to update must be a Secondary node.");

            //validate for duplicate names
            foreach (KeyValuePair<int, ClusterNode> clusterNode in clusterNodes)
            {
                if (clusterNode.Key == secondaryNodeId)
                    continue; //skip self

                if (clusterNode.Value.Name.Equals(secondaryNodeUrl.Host, StringComparison.OrdinalIgnoreCase))
                    throw new DnsServerException("Failed to update Secondary node: A node with the same DNS Server Domain Name already exists in the Cluster. Please try again after changing the Secondary node's DNS Server Domain Name.");
            }

            bool secondaryNodeDomainChanged = !secondaryNode.Name.Equals(secondaryNodeUrl.Host, StringComparison.OrdinalIgnoreCase);

            //find existing record TTL values
            FindExistingRecordTtlValues(out uint nsTtl, out uint aTtl);

View on GitHub (pinned to d0484b6c1e)

Solutions

  1. Refresh the node list from the cluster and use a current Secondary node ID
  2. Confirm the ID exists immediately before calling, especially under concurrency
  3. Distinguish node ID (int) from list index

Example fix

// before
clusterManager.UpdateSecondaryNode(maybeStaleId, url, ips, cert);

// after
var node = clusterState.ClusterNodes
    .FirstOrDefault(n => n.Id == id && n.Type == ClusterNodeType.Secondary);
if (node is null) throw new ArgumentException("Secondary node not found; refresh the node list.");
clusterManager.UpdateSecondaryNode(node.Id, url, ips, cert);
Defensive patterns

Strategy: validation

Validate before calling

if (!clusterState.ClusterNodes.Any(n => n.Id == secondaryNodeId))
    return NotFound("Secondary node ID does not exist.");
clusterManager.UpdateSecondaryNode(secondaryNodeId, url, ips, cert);

Try / catch

catch (DnsServerException ex) when (ex.Message.Contains("does not exist in the Cluster"))
{ /* refresh node list and re-prompt */ }

Prevention

When it happens

Trigger: Passing a stale or already-removed node ID; using an array index instead of the node's actual ID; the node was deleted by a concurrent operation before this call ran.

Common situations: Cached node list gone stale; off-by-one between list position and node ID; a race where another admin deleted the node first.

Related errors


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