TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to delete Secondary node: the specified node is the C
Error message
Failed to delete Secondary node: the specified node is the Cluster Primary node and cannot be deleted.
What it means
Thrown by DeleteSecondaryNode when the supplied node ID resolves to the cluster's Primary node (ClusterNodeType.Primary). The cluster topology requires exactly one Primary, and deleting it would orphan the cluster, so the operation is rejected. The check fires after the node lookup succeeds, so the ID is valid but of the wrong role.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:779
return secondaryNode;
}
public ClusterNode DeleteSecondaryNode(int secondaryNodeId)
{
if (!ClusterInitialized)
throw new DnsServerException("Failed to delete Secondary node: the Cluster is not initialized.");
if (GetSelfNode().Type != ClusterNodeType.Primary)
throw new DnsServerException("Failed to delete Secondary node: only a Primary node can delete a Secondary node from the Cluster.");
//find existing secondary node
IReadOnlyDictionary<int, ClusterNode> existingClusterNodes = _clusterNodes;
if (!existingClusterNodes.TryGetValue(secondaryNodeId, out ClusterNode secondaryNode))
throw new DnsServerException("Failed to delete Secondary node: the specified node does not exist in the Cluster.");
if (secondaryNode.Type == ClusterNodeType.Primary)
throw new DnsServerException("Failed to delete Secondary node: the specified node is the Cluster Primary node and cannot be deleted.");
//delete secondary node from cluster nodes
Dictionary<int, ClusterNode> updatedClusterNodes = new Dictionary<int, ClusterNode>(existingClusterNodes.Count - 1);
foreach (KeyValuePair<int, ClusterNode> existingClusterNode in existingClusterNodes)
{
if (existingClusterNode.Key == secondaryNodeId)
continue;
updatedClusterNodes[existingClusterNode.Key] = existingClusterNode.Value;
}
IReadOnlyDictionary<int, ClusterNode> originalValue = Interlocked.CompareExchange(ref _clusterNodes, updatedClusterNodes, existingClusterNodes);
if (!ReferenceEquals(originalValue, existingClusterNodes))
throw new InvalidOperationException("Failed to delete Secondary node: please try again.");
secondaryNode.Dispose();
View on GitHub (pinned to d0484b6c1e)
Solutions
- Pass the Secondary node's ID, not the Primary's - obtain it from the live cluster state and filter Type == Secondary
- Exclude the Primary (GetSelfNode()) from any batch-delete loop
- To remove the Primary, demote/leave the cluster instead of calling DeleteSecondaryNode
Example fix
// before
foreach (var id in allNodeIds) mgr.DeleteSecondaryNode(id);
// after
foreach (var node in clusterNodes.Where(n => n.Type == ClusterNodeType.Secondary))
mgr.DeleteSecondaryNode(node.Id); Defensive patterns
Strategy: validation
Validate before calling
var target = clusterState.ClusterNodes.FirstOrDefault(n => n.Id == secondaryNodeId);
if (target is null) throw new ArgumentException("node not found");
if (target.Type == ClusterNodeType.Primary)
throw new InvalidOperationException("Cannot delete the Primary node; choose a Secondary node.");
clusterManager.DeleteSecondaryNode(secondaryNodeId); Try / catch
try { clusterManager.DeleteSecondaryNode(id); }
catch (DnsServerException ex) when (ex.Message.Contains("Cluster Primary node"))
{ /* skip primary; log and continue */ } Prevention
- Derive the node list from live cluster state and filter to Secondary before deleting
- Never feed GetSelfNode().Id into DeleteSecondaryNode
When it happens
Trigger: Calling DeleteSecondaryNode(primaryNodeId) on the Primary; an automation loop that iterates every node ID and calls delete on each; passing GetSelfNode().Id by accident.
Common situations: Admin UI or script that does not filter the node list by type before deletion; copy-pasting the wrong ID; treating 'remove this server from cluster' as 'delete node' on the Primary itself.
Related errors
- 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: the Cluster is not initiali
- Failed to update Secondary node: the specified node does not
- 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/493e32da2d08fbdb.
Report an issue: GitHub.