{"record":{"id":"d411bf8789c14cbb","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-join-cluster-the-primary-node-does-not","errorCode":null,"errorMessage":"Failed to join Cluster: the Primary node does not have a Cluster initialized.","messagePattern":"Failed to join Cluster: the Primary node does not have a Cluster initialized\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":1371,"sourceCode":"            using HttpApiClient primaryNodeApiClient = new HttpApiClient(primaryNodeUrl, _dnsWebService.DnsServer.Proxy, _dnsWebService.DnsServer.IPv6Mode, ignoreCertificateErrors, new InternalDnsClient(_dnsWebService.DnsServer, primaryNodeIpAddresses));\n\n            try\n            {\n                _ = await primaryNodeApiClient.LoginAsync(primaryNodeUsername, primaryNodePassword, primaryNodeTotp, false, cancellationToken);\n            }\n            catch (TwoFactorAuthRequiredHttpApiClientException ex)\n            {\n                throw new TwoFactorAuthRequiredWebServiceException(\"Failed to join Cluster: two-factor authentication is required by the Primary node user account.\", ex);\n            }\n\n            try\n            {\n                //get cluster info\n                ClusterInfo primaryNodeClusterInfo = await primaryNodeApiClient.GetClusterStateAsync(cancellationToken: cancellationToken);\n\n                //do validations\n                if (!primaryNodeClusterInfo.ClusterInitialized)\n                    throw new DnsServerException(\"Failed to join Cluster: the Primary node does not have a Cluster initialized.\");\n\n                string clusterCatalogDomain = \"cluster-catalog.\" + primaryNodeClusterInfo.ClusterDomain;\n\n                if (_dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(clusterCatalogDomain) is not null)\n                    throw new DnsServerException($\"Failed to join Cluster: the zone '{clusterCatalogDomain}' already exists. Please delete the '{clusterCatalogDomain}' zone and try again.\");\n\n                if (_dnsWebService.DnsServer.AuthZoneManager.GetAuthZoneInfo(primaryNodeClusterInfo.ClusterDomain) is not null)\n                    throw new DnsServerException($\"Failed to join Cluster: the zone '{primaryNodeClusterInfo.ClusterDomain}' already exists. Please delete the '{primaryNodeClusterInfo.ClusterDomain}' zone and try again.\");\n\n                //create self node\n                string serverDomain = _dnsWebService.DnsServer.ServerDomain;\n                if (!serverDomain.EndsWith(\".\" + primaryNodeClusterInfo.ClusterDomain, StringComparison.OrdinalIgnoreCase))\n                {\n                    int x = serverDomain.IndexOf('.');\n                    if (x < 0)\n                        serverDomain = serverDomain + \".\" + primaryNodeClusterInfo.ClusterDomain;\n                    else\n                        serverDomain = string.Concat(serverDomain.AsSpan(0, x), \".\", primaryNodeClusterInfo.ClusterDomain);","sourceCodeStart":1353,"sourceCodeEnd":1389,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L1353-L1389","documentation":"The would-be Secondary contacted the Primary and learned (via GetClusterStateAsync) that the Primary itself has no cluster initialized. You can only join a Primary that already created a cluster.","triggerScenarios":"Joining a node that is standalone; the operator ran 'join' before 'create cluster' on the intended Primary; pointing at the wrong server.","commonSituations":"Wrong Primary URL; Primary cluster creation failed or was reverted; targeting a fresh install.","solutions":["Create the cluster on the intended Primary first, then join","Verify the target URL points to the actual cluster Primary","Retry join after Primary initialization completes"],"exampleFix":"// before\nawait clusterManager.InitializeAndJoinClusterAsync(ips, primaryUrl, user, pass);\n\n// after\nvar info = await primaryNodeApiClient.GetClusterStateAsync();\nif (!info.ClusterInitialized)\n    throw new InvalidOperationException(\"Primary has no cluster; create it first.\");\nawait clusterManager.InitializeAndJoinClusterAsync(ips, primaryUrl, user, pass);","handlingStrategy":"validation","validationCode":"var info = await primaryNodeApiClient.GetClusterStateAsync(ct);\nif (!info.ClusterInitialized)\n    return BadRequest(\"Target Primary has no cluster initialized.\");\nawait clusterManager.InitializeAndJoinClusterAsync(ips, primaryUrl, user, pass);","typeGuard":null,"tryCatchPattern":"catch (DnsServerException ex) when (ex.Message.Contains(\"does not have a Cluster initialized\"))\n{ /* instruct: create cluster on Primary first */ }","preventionTips":["Verify the Primary's cluster state before attempting join","Document the create-then-join ordering for operators"],"tags":["cluster","lifecycle","join","validation","dns-server"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}