TechnitiumSoftware/DnsServer · warning · InvalidOperationException
Failed to delete Secondary node: please try again.
Error message
Failed to delete Secondary node: please try again.
What it means
Thrown as InvalidOperationException when the lock-free swap of the cluster node table fails. DeleteSecondaryNode snapshots _clusterNodes, builds a copy without the target, then publishes it via Interlocked.CompareExchange; if another thread changed _clusterNodes in between, the swap is aborted and you are told to retry. This is a transient optimistic-concurrency conflict, not data corruption.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:794
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();
//update cluster zone and save zone file
RemoveClusterPrimaryZoneRecordsFor(secondaryNode);
//update cluster catalog zone ACLs and save zone file
UpdateClusterCatalogZoneOptions();
//save all changes
SaveConfigFile();
//notify all secondary nodes
TriggerNotifyAllSecondaryNodes();
//trigger NS and SOA update for member zones
TriggerRecordUpdateForClusterCatalogMemberZones();
View on GitHub (pinned to d0484b6c1e)
Solutions
- Retry the identical DeleteSecondaryNode call - the snapshot refreshes and the swap should succeed
- Serialize cluster-mutation calls behind a single client-side queue/lock
- Allow only one outstanding cluster topology change at a time
Example fix
// before
clusterManager.DeleteSecondaryNode(id);
// after
for (int attempt = 0; ; attempt++)
{
try { clusterManager.DeleteSecondaryNode(id); break; }
catch (InvalidOperationException ex) when (ex.Message.Contains("please try again") && attempt < 5)
await Task.Delay(TimeSpan.FromMilliseconds(200 * (attempt + 1)));
} Defensive patterns
Strategy: retry
Try / catch
catch (InvalidOperationException ex) when (ex.Message.Contains("please try again"))
{
// transient optimistic-concurrency conflict; retry after brief backoff
} Prevention
- Treat InvalidOperationException 'please try again' as transient and retry with backoff
- Funnel all cluster topology mutations through a single serialized queue
When it happens
Trigger: Two concurrent Delete/Add/Update Secondary calls on the same Primary; a 'remove node' button clicked twice quickly; parallel admin scripts mutating cluster topology.
Common situations: Concurrent cluster mutations under load; a retry storm from an impatient operator; a race between a heartbeat-driven update and an admin delete.
Related errors
- Failed to add Secondary node: please try again.
- Failed to initialize Cluster: failed to create the Cluster C
- 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
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/5de5df02e022b21e.
Report an issue: GitHub.