TechnitiumSoftware/DnsServer · error · DnsServerException
Failed to join Cluster: the zone '{clusterCatalogDomain}' al
Error message
Failed to join Cluster: the zone '{clusterCatalogDomain}' already exists. Please delete the '{clusterCatalogDomain}' zone and try again. What it means
Before joining, the Secondary checks its local zones and finds 'cluster-catalog.<clusterDomain>' already exists. Joining would create this catalog zone, so a pre-existing one (from a prior or aborted join) blocks the operation.
Source
Thrown at DnsServerCore/Cluster/ClusterManager.cs:1376
}
catch (TwoFactorAuthRequiredHttpApiClientException ex)
{
throw new TwoFactorAuthRequiredWebServiceException("Failed to join Cluster: two-factor authentication is required by the Primary node user account.", ex);
}
try
{
//get cluster info
ClusterInfo primaryNodeClusterInfo = await primaryNodeApiClient.GetClusterStateAsync(cancellationToken: cancellationToken);
//do validations
if (!primaryNodeClusterInfo.ClusterInitialized)
throw new DnsServerException("Failed to join Cluster: the Primary node does not have a Cluster initialized.");
string clusterCatalogDomain = "cluster-catalog." + primaryNodeClusterInfo.ClusterDomain;
if (_dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(clusterCatalogDomain) is not null)
throw new DnsServerException($"Failed to join Cluster: the zone '{clusterCatalogDomain}' already exists. Please delete the '{clusterCatalogDomain}' zone and try again.");
if (_dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(primaryNodeClusterInfo.ClusterDomain) is not null)
throw new DnsServerException($"Failed to join Cluster: the zone '{primaryNodeClusterInfo.ClusterDomain}' already exists. Please delete the '{primaryNodeClusterInfo.ClusterDomain}' zone and try again.");
//create self node
string serverDomain = _dnsWebService.DnsServer.ServerDomain;
if (!serverDomain.EndsWith("." + primaryNodeClusterInfo.ClusterDomain, StringComparison.OrdinalIgnoreCase))
{
int x = serverDomain.IndexOf('.');
if (x < 0)
serverDomain = serverDomain + "." + primaryNodeClusterInfo.ClusterDomain;
else
serverDomain = string.Concat(serverDomain.AsSpan(0, x), ".", primaryNodeClusterInfo.ClusterDomain);
}
Uri secondaryNodeUrl = new Uri($"https://{serverDomain}:{_dnsWebService.WebServiceTlsPort}/");
ClusterNode selfSecondaryNode = new ClusterNode(this, RandomNumberGenerator.GetInt32(int.MaxValue), secondaryNodeUrl, secondaryNodeIpAddresses, ClusterNodeType.Secondary, ClusterNodeState.Self);View on GitHub (pinned to d0484b6c1e)
Solutions
- Delete the existing 'cluster-catalog.<clusterDomain>' zone, then retry join
- Fully leave/reset the previous cluster to clean up catalog zones
- Verify no stale catalog zones remain before join
Example fix
// before
await clusterManager.InitializeAndJoinClusterAsync(ips, primaryUrl, user, pass);
// after
var catalog = "cluster-catalog." + info.ClusterDomain;
if (dnsServer.AuthZoneManager.GetAuthZoneInfo(catalog) is not null)
dnsServer.AuthZoneManager.DeleteZone(catalog);
await clusterManager.InitializeAndJoinClusterAsync(ips, primaryUrl, user, pass); Defensive patterns
Strategy: validation
Validate before calling
string catalog = "cluster-catalog." + info.ClusterDomain;
if (dnsServer.AuthZoneManager.GetAuthZoneInfo(catalog) is not null)
return Conflict($"Zone '{catalog}' exists; delete it before joining.");
await clusterManager.InitializeAndJoinClusterAsync(ips, primaryUrl, user, pass); Try / catch
catch (DnsServerException ex) when (ex.Message.Contains("cluster-catalog") && ex.Message.Contains("already exists"))
{ /* offer to delete the stale catalog zone then retry */ } Prevention
- Clean up cluster-catalog zones after leaving or aborting a join
- Check for pre-existing cluster zones before joining
When it happens
Trigger: Re-joining after a failed or partial join left the catalog zone behind; importing a config that already had the catalog zone; a leftover zone from a different cluster.
Common situations: Retry of join after a crash; restoring from backup that included cluster zones; partial cleanup after leaving a cluster.
Related errors
- Failed to join Cluster: the zone '{primaryNodeClusterInfo.Cl
- Failed to join Cluster: the Primary node does not have a Clu
- Failed to update Secondary node: the Cluster is not initiali
- Failed to transfer configuration: the Cluster is not initial
- Failed to update Cluster options: the Cluster is not initial
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/fb1ad2d43421d509.
Report an issue: GitHub.