{"record":{"id":"c156d535107bcfc5","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-initialize-cluster-the-zone-clusterca","errorCode":null,"errorMessage":"Failed to initialize Cluster: the zone '{clusterCatalogZoneInfo.Name}' already exists and is not a Catalog zone. Please delete the existing zone or use a different Cluster domain name.","messagePattern":"Failed to initialize Cluster: the zone '(.+?)' already exists and is not a Catalog zone\\. Please delete the existing zone or use a different Cluster domain name\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":573,"sourceCode":"            }\n            else if (clusterZoneInfo.Type != AuthZoneType.Primary)\n            {\n                throw new DnsServerException($\"Failed to initialize Cluster: the zone '{clusterZoneInfo.Name}' already exists and is not a Primary zone. Please delete the existing zone or use a different Cluster domain name.\");\n            }\n\n            //create cluster catalog zone\n            string clusterCatalogDomain = \"cluster-catalog.\" + clusterDomain;\n\n            AuthZoneInfo clusterCatalogZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(clusterCatalogDomain);\n            if (clusterCatalogZoneInfo is null)\n            {\n                clusterCatalogZoneInfo = _dnsWebService.DnsServer.AuthZoneManager.CreateCatalogZone(clusterCatalogDomain);\n                if (clusterCatalogZoneInfo is null)\n                    throw new DnsServerException($\"Failed to initialize Cluster: failed to create the Cluster Catalog zone '{clusterCatalogDomain}'. Please try again.\");\n            }\n            else if (clusterCatalogZoneInfo.Type != AuthZoneType.Catalog)\n            {\n                throw new DnsServerException($\"Failed to initialize Cluster: the zone '{clusterCatalogZoneInfo.Name}' already exists and is not a Catalog zone. Please delete the existing zone or use a different Cluster domain name.\");\n            }\n\n            //set cluster primary zone permissions\n            _dnsWebService.AuthManager.SetPermission(PermissionSection.Zones, clusterZoneInfo.Name, _dnsWebService.AuthManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);\n            _dnsWebService.AuthManager.SetPermission(PermissionSection.Zones, clusterZoneInfo.Name, _dnsWebService.AuthManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.View);\n\n            //set cluster catalog zone permissions\n            _dnsWebService.AuthManager.SetPermission(PermissionSection.Zones, clusterCatalogZoneInfo.Name, _dnsWebService.AuthManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);\n            _dnsWebService.AuthManager.SetPermission(PermissionSection.Zones, clusterCatalogZoneInfo.Name, _dnsWebService.AuthManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.View);\n\n            //ensure cluster zone is a member of cluster catalog zone\n            if (clusterZoneInfo.CatalogZoneName is null)\n                _dnsWebService.DnsServer.AuthZoneManager.AddCatalogMemberZone(clusterCatalogZoneInfo.Name, clusterZoneInfo);\n            else if (!clusterZoneInfo.CatalogZoneName.Equals(clusterCatalogZoneInfo.Name, StringComparison.OrdinalIgnoreCase))\n                _dnsWebService.DnsServer.AuthZoneManager.ChangeCatalogMemberZoneOwnership(clusterZoneInfo, clusterCatalogZoneInfo.Name);\n\n            //sign cluster zone\n            if (clusterZoneInfo.ApexZone.DnssecStatus == AuthZoneDnssecStatus.Unsigned)","sourceCodeStart":555,"sourceCodeEnd":591,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L555-L591","documentation":"Thrown by InitializeCluster when the catalog zone name ('cluster-catalog.' + clusterDomain) already exists but is not of type AuthZoneType.Catalog. The catalog zone is a special zone type used for XFR-based replication of member zones; a non-catalog zone under that name cannot serve that purpose, so initialization aborts.","triggerScenarios":"InitializeCluster is called when GetAuthZoneInfo('cluster-catalog.{domain}') returns a non-null zone whose Type is not AuthZoneType.Catalog (e.g., it was created as Primary, Secondary, Stub, or Forwarder). The else-if at line 571 fires.","commonSituations":"Leftover catalog zone from a previous cluster that was manually converted to another type; a user-created zone with the 'cluster-catalog.' prefix; partial cleanup after a failed or aborted cluster initialization that left a primary zone behind under the catalog name.","solutions":["Delete the existing zone named 'cluster-catalog.{domain}' so InitializeCluster can create a proper catalog zone, then retry.","Use a different cluster domain name to avoid the naming collision entirely."],"exampleFix":"// before\n_dnsWebService.ClusterManager.InitializeCluster(\"dns.example.com\", ips, session);\n// after\nvar catalogZone = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(\"cluster-catalog.dns.example.com\");\nif (catalogZone is not null && catalogZone.Type != AuthZoneType.Catalog)\n    _dnsWebService.DnsServer.AuthZoneManager.DeleteZone(catalogZone.Name);\n_dnsWebService.ClusterManager.InitializeCluster(\"dns.example.com\", ips, session);","handlingStrategy":"validation","validationCode":"// Check for a conflicting non-catalog catalog-zone before initializing\nstring clusterDomain = \"dns.example.com\";\nstring catalogDomain = \"cluster-catalog.\" + clusterDomain;\nvar catalogZone = _dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(catalogDomain);\nif (catalogZone is not null && catalogZone.Type != AuthZoneType.Catalog)\n    throw new InvalidOperationException($\"Zone '{catalogZone.Name}' exists as {catalogZone.Type}; delete it before InitializeCluster.\");\n_dnsWebService.ClusterManager.InitializeCluster(clusterDomain, ips, session);","typeGuard":"static bool IsCatalogZoneSafeForClusterInit(AuthZoneInfo zone, string catalogDomain)\n    => zone is null || (zone.Name.Equals(catalogDomain, StringComparison.OrdinalIgnoreCase) && zone.Type == AuthZoneType.Catalog);","tryCatchPattern":"try\n{\n    _dnsWebService.ClusterManager.InitializeCluster(clusterDomain, ips, session);\n}\ncatch (DnsServerException ex) when (ex.Message.Contains(\"already exists and is not a Catalog zone\"))\n{\n    throw new InvalidOperationException(\"The cluster-catalog zone name is taken by a non-catalog zone. Delete it or use a different domain.\", ex);\n}","preventionTips":["Before InitializeCluster, check GetAuthZoneInfo for 'cluster-catalog.{domain}' and ensure it is absent or Catalog type.","Do not manually create zones with the 'cluster-catalog.' prefix.","Clean up catalog zones left by aborted cluster setups."],"tags":["cluster","dns-zone","catalog","initialization","zone-conflict"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}