TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to update Primary node: the specified node is the sel
Error message
Failed to update Primary node: the specified node is the self node and cannot be updated this way.
What it means
Thrown by UpdatePrimaryNodeAsync when the node selected by primaryNodeId resolves to the self node (primaryNode.State == ClusterNodeState.Self). UpdatePrimaryNodeAsync is meant to point at a *remote* primary; updating the self node's own address via this API is not permitted because it would rewrite the local node's identity from under itself.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:1539
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)
{
if (existingClusterNode.Key == formerPrimaryNode.Id)
continue;
View on GitHub (pinned to d0484b6c1e)
Solutions
- Select a different, remote node Id (or pass -1 if you genuinely mean the current remote primary).
- Filter the self node out of any 'pick primary' UI list before submission.
- If you meant to change this server's own advertised URL, use the node's own UpdateNode path rather than UpdatePrimaryNodeAsync.
Example fix
// before
await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: pickedId);
// after
if (clusterManager.ClusterNodes[pickedId].State == ClusterNodeState.Self)
return BadRequest("Cannot target the self node via update-primary.");
await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: pickedId); Defensive patterns
Strategy: validation
Validate before calling
if (primaryNodeId >= 0 && clusterManager.ClusterNodes[primaryNodeId].State == ClusterNodeState.Self)
return BadRequest("Cannot target the self node via update-primary.");
await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: primaryNodeId); Type guard
static bool IsSelfNodeId(ClusterManager cm, int id)
=> id >= 0 && cm.ClusterNodes.TryGetValue(id, out var n) && n.State == ClusterNodeState.Self; Try / catch
try { await clusterManager.UpdatePrimaryNodeAsync(primaryUrl, primaryNodeId: id); }
catch (DnsServerException ex) when (ex.Message.Contains("self node and cannot be updated"))
{ /* pick a remote node id instead */ } Prevention
- Exclude the self node from 'pick primary' selection lists.
- Prefer -1 (current primary) unless you specifically need to target a remote node.
- Validate the selected id is not the self node before submitting.
When it happens
Trigger: Passing a primaryNodeId that equals this server's own node Id, on a server that is currently the primary (so GetPrimaryNode() is Self).
Common situations: Operator selected their own node in a 'choose new primary' dropdown; automation passed the self node's Id by mistake; the cluster has only one node and the caller tried to 'update' it.
Related errors
- Failed to leave Cluster: a Primary self node cannot leave th
- Failed to leave Cluster: only Secondary nodes can leave the
- 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
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/8ad541df0374bade.
Report an issue: GitHub.