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
- Refresh the node list from the cluster and use a current Secondary node ID
- Confirm the ID exists immediately before calling, especially under concurrency
- 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
- Never cache node IDs across long-lived sessions - re-fetch cluster state
- Validate the ID against the live node table right before mutating
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
- Failed to delete Secondary node: the specified node is the C
- Failed to update Secondary node: the Cluster is not initiali
- Failed to update Secondary node: only a Primary node can upd
- Failed to update Secondary node: the specified node to updat
- Failed to update Secondary node: A node with the same DNS Se
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/2001d1a9a03ea1fa.
Report an issue: GitHub.