{"record":{"id":"dab6757b06867535","repo":"kubernetes/kops","slug":"unable-to-resolve-kubernetes-cluster-api-url-dns","errorCode":null,"errorMessage":"unable to resolve Kubernetes cluster API URL dns: %v","messagePattern":"unable to resolve Kubernetes cluster API URL dns: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/validation/validate_cluster.go","lineNumber":101,"sourceCode":"\n// ValidationNode represents the validation status for a node\ntype ValidationNode struct {\n\tName     string             `json:\"name,omitempty\"`\n\tZone     string             `json:\"zone,omitempty\"`\n\tRole     string             `json:\"role,omitempty\"`\n\tHostname string             `json:\"hostname,omitempty\"`\n\tStatus   v1.ConditionStatus `json:\"status,omitempty\"`\n}\n\n// hasPlaceHolderIP checks if the API DNS has been updated.\nfunc hasPlaceHolderIP(host string) (string, error) {\n\tapiAddr, err := url.Parse(host)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to parse Kubernetes cluster API URL: %v\", err)\n\t}\n\thostAddrs, err := net.LookupHost(apiAddr.Hostname())\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to resolve Kubernetes cluster API URL dns: %v\", err)\n\t}\n\n\tsort.Strings(hostAddrs)\n\tfor _, h := range hostAddrs {\n\t\tif h == dns.PlaceholderIP || h == dns.PlaceholderIPv6 {\n\t\t\treturn h, nil\n\t\t}\n\t}\n\n\treturn \"\", nil\n}\n\nfunc NewClusterValidator(cluster *kops.Cluster, cloud fi.Cloud, instanceGroupList *kops.InstanceGroupList, filterInstanceGroups func(ig *kops.InstanceGroup) bool, filterPodsForValidation func(pod *v1.Pod) bool, maxUnreadyNodes int, restConfig *rest.Config, k8sClient kubernetes.Interface) (ClusterValidator, error) {\n\tvar allInstanceGroups []*kops.InstanceGroup\n\n\tfor i := range instanceGroupList.Items {\n\t\tig := &instanceGroupList.Items[i]\n\t\tallInstanceGroups = append(allInstanceGroups, ig)","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/validation/validate_cluster.go#L83-L119","documentation":"hasPlaceHolderIP resolves the cluster API hostname via net.LookupHost to see if DNS still returns kOps' placeholder IP (203.0.113.123 / ::1:1:1... style). If the hostname cannot be resolved at all, this error is returned — the API DNS record does not exist or DNS is unreachable. Validation cannot proceed because it cannot determine whether the API endpoint is live.","triggerScenarios":"net.LookupHost(apiAddr.Hostname()) returns an error: the API DNS record was never created, was deleted, or DNS servers are unreachable from the machine running validation (NXDOMAIN / no such host / i/o timeout).","commonSituations":"Running kops validate cluster before DNS propagation after cluster creation; internal (private) API endpoint validated from outside the VPC; Route53/Cloud DNS hosted zone misconfigured; corporate VPN or resolver not forwarding the zone.","solutions":["Verify the DNS record exists: dig/nslookup api.<cluster> and compare against the hosted zone (kops toolbox dns... or your DNS console)","Wait for DNS propagation if the cluster was just created, then re-run kops validate cluster","Run validation from inside the VPC / with a resolver that can see the private zone if the API is internal","Check network egress (UDP/TCP 53) and VPN/route settings if resolution times out"],"exampleFix":"// before\n$ kops validate cluster\n# unable to resolve Kubernetes cluster API URL dns: lookup api.mycluster.example.com: no such host\n// after\n$ dig api.mycluster.example.com   # confirm the A record exists\n$ kops validate cluster           # succeeds once DNS resolves","handlingStrategy":"retry","validationCode":"_, err := net.LookupHost(hostFromURL(apiURL))\nif err != nil {\n    return fmt.Errorf(\"API host %s not resolvable yet: %v\", hostFromURL(apiURL), err)\n}","typeGuard":null,"tryCatchPattern":"var ph string\nerr := retry.OnError(wait.Backoff{Steps: 6, Duration: 10 * time.Second},\n    func(err error) bool { return isDNSTempFailure(err) },\n    func() (err error) { ph, err = hasPlaceHolderIP(apiURL); return err })\nif err != nil {\n    return fmt.Errorf(\"API DNS still unresolvable: %w\", err)\n}","preventionTips":["Wait for DNS propagation after cluster creation before validating","Validate private-API clusters from inside the VPC","Monitor the hosted zone record for the API endpoint","Check resolver/VPN config when validation runs from CI networks"],"tags":["go","dns","network","kops","validation"],"backgroundTag":"dns-resolution-failure","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}