TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to update Primary node: the specified Primary node ID
Error message
Failed to update Primary node: the specified Primary node ID does not exists in the Cluster.
What it means
Thrown by UpdatePrimaryNodeAsync when a non-negative primaryNodeId was supplied but no entry with that key exists in _clusterNodes (TryGetValue returned false). The method uses primaryNodeId < 0 as 'use the current primary', so any explicit ID must match an existing cluster node's Id.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:1536
{
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;
if (primaryNodeId < 0)
primaryNode = GetPrimaryNode();
else if (!_clusterNodes.TryGetValue(primaryNodeId, out primaryNode))
throw new DnsServerException("Failed to update Primary node: the specified Primary node ID does not exists in the Cluster.");
if (primaryNode.State == ClusterNodeState.Self)
throw new DnsServerException("Failed to update Primary node: the specified node is the self node and cannot be updated this way.");
if (primaryNode.Type == ClusterNodeType.Secondary)
{
//secondary node was promoted to primary node
ClusterNode formerPrimaryNode = GetPrimaryNode();
//dispose former primary node immediately to stop heartbeat
formerPrimaryNode.Dispose();
//remove former primary node from cluster nodes
IReadOnlyDictionary<int, ClusterNode> existingClusterNodes = _clusterNodes;
Dictionary<int, ClusterNode> updatedClusterNodes = new Dictionary<int, ClusterNode>(existingClusterNodes.Count - 1);
foreach (KeyValuePair<int, ClusterNode> existingClusterNode in existingClusterNodes)
{View on GitHub (pinned to d0484b6c1e)
Solutions
- Omit primaryNodeId (or pass -1) to target the current primary automatically.
- Refresh the cluster node list and pass a currently-valid Id from clusterManager.ClusterNodes.
- Validate the ID against ClusterNodes.Keys before calling the API.
Example fix
// before
await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: requestedId);
// after
if (requestedId >= 0 && !clusterManager.ClusterNodes.ContainsKey(requestedId))
return NotFound($"Node {requestedId} not in cluster.");
await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: requestedId); Defensive patterns
Strategy: validation
Validate before calling
if (primaryNodeId >= 0 && !clusterManager.ClusterNodes.ContainsKey(primaryNodeId))
return NotFound($"Node {primaryNodeId} is not in the cluster.");
await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: primaryNodeId); Type guard
static bool IsValidNodeId(ClusterManager cm, int id) => id < 0 || cm.ClusterNodes.ContainsKey(id);
Try / catch
try { await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: id); }
catch (DnsServerException ex) when (ex.Message.Contains("ID does not exists"))
{ /* refresh node list and retry with a current id, or pass -1 */ } Prevention
- Pass -1 (or omit) when you mean 'the current primary'.
- Refresh the cluster node list before submitting an explicit id.
- Validate id against ClusterNodes.Keys at the API boundary.
When it happens
Trigger: Calling UpdatePrimaryNodeAsync with a stale, wrong, or deleted primaryNodeId — e.g. an ID from a node that has since been removed, an ID copied from a different cluster, or a default/placeholder value that happened to be non-negative.
Common situations: UI passed a cached node ID after the cluster topology changed; client serialized the wrong numeric ID; a node was deleted between the UI list load and the update submit; off-by-one or type confusion passing a port/counter as the ID.
Related errors
- Failed to update Primary node: the Primary node's domain nam
- Failed to update Primary node: the Cluster is not initialize
- The domain name '{primaryNodeUrl.Host}' does not have an A/A
- Failed to update Primary node: the Primary node domain name
- Failed to update Primary node: the specified node is the sel
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/58c5785e566dca61.
Report an issue: GitHub.