{"record":{"id":"af00f380c2771ccf","repo":"TechnitiumSoftware/DnsServer","slug":"failed-to-join-cluster-the-primary-node-domain-na","errorCode":null,"errorMessage":"Failed to join Cluster: the Primary node domain name '{primaryNodeUrl.Host}' could not be resolved to an IP address. Please specify the Primary node IP address manually.","messagePattern":"Failed to join Cluster: the Primary node domain name '(.+?)' could not be resolved to an IP address\\. Please specify the Primary node IP address manually\\.","errorType":"exception","errorClass":"DnsServerException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Cluster/ClusterManager.cs","lineNumber":1348,"sourceCode":"            if (!_dnsWebService.IsWebServiceTlsEnabled)\n                throw new InvalidOperationException();\n\n            if (IPAddress.TryParse(primaryNodeUrl.Host, out _))\n                throw new DnsServerException(\"Failed to join Cluster: the Primary Node URL must use the domain name of the Primary node and not its IP address.\");\n\n            if (primaryNodeIpAddresses is null)\n            {\n                try\n                {\n                    IReadOnlyList<IPAddress> ipAddresses = await DnsClient.ResolveIPAsync(_dnsWebService.DnsServer, primaryNodeUrl.Host, _dnsWebService.DnsServer.IPv6Mode, cancellationToken);\n                    if (ipAddresses.Count < 1)\n                        throw new DnsServerException($\"Failed to join Cluster: the domain name '{primaryNodeUrl.Host}' does not have an A/AAAA record configured.\");\n\n                    primaryNodeIpAddresses = ipAddresses;\n                }\n                catch (Exception ex)\n                {\n                    throw new DnsServerException($\"Failed to join Cluster: the Primary node domain name '{primaryNodeUrl.Host}' could not be resolved to an IP address. Please specify the Primary node IP address manually.\", ex);\n                }\n            }\n\n            //login to primary node API\n            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","sourceCodeStart":1330,"sourceCodeEnd":1366,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Cluster/ClusterManager.cs#L1330-L1366","documentation":"During join, resolving the Primary's domain name threw an exception (the DNS lookup failed entirely). The wrapper re-throws with a hint to supply the IP manually via primaryNodeIpAddresses.","triggerScenarios":"Resolver unreachable; NXDOMAIN for the Primary host; SERVFAIL; a network or DNS outage on the joining node; the configured upstream resolver cannot answer.","commonSituations":"The joining node has no working DNS path to resolve the Primary; a firewall blocking DNS; a misconfigured upstream resolver; a transient DNS failure.","solutions":["Pass primaryNodeIpAddresses explicitly to skip resolution","Fix the joining node's DNS/upstream resolver and network","Verify the Primary hostname exists in a resolvable zone"],"exampleFix":"// before\nawait clusterManager.InitializeAndJoinClusterAsync(null, primaryUrl, user, pass);\n\n// after\nawait clusterManager.InitializeAndJoinClusterAsync(\n    secondaryNodeIpAddresses, primaryUrl, user, pass,\n    primaryNodeIpAddresses: new[] { IPAddress.Parse(\"10.0.0.5\") });","handlingStrategy":"fallback","validationCode":"IReadOnlyList<IPAddress> primaryIps;\ntry { primaryIps = await DnsClient.ResolveIPAsync(dnsServer, primaryUrl.Host, dnsServer.IPv6Mode, ct); }\ncatch { primaryIps = userProvidedPrimaryIps; }\nif (primaryIps is null || primaryIps.Count == 0)\n    return BadRequest(\"Cannot resolve Primary; provide its IP manually.\");\nawait clusterManager.InitializeAndJoinClusterAsync(ips, primaryUrl, user, pass, primaryNodeIpAddresses: primaryIps);","typeGuard":null,"tryCatchPattern":"catch (DnsServerException ex) when (ex.Message.Contains(\"could not be resolved\"))\n{ /* fall back to user-supplied Primary IP and retry join */ }","preventionTips":["Offer a manual Primary IP field in the join UI as a DNS fallback","Validate the joining node's upstream resolver before join"],"tags":["cluster","network","dns-resolution","join","dns-server"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}