kubernetes/kops · error

unable to resolve Kubernetes cluster API URL dns

Error message

unable to resolve Kubernetes cluster API URL dns: %v

What it means

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.

Solutions

  1. Verify the DNS record exists: dig/nslookup api.<cluster> and compare against the hosted zone (kops toolbox dns... or your DNS console)
  2. Wait for DNS propagation if the cluster was just created, then re-run kops validate cluster
  3. Run validation from inside the VPC / with a resolver that can see the private zone if the API is internal
  4. Check network egress (UDP/TCP 53) and VPN/route settings if resolution times out

Example fix

// before
$ kops validate cluster
# unable to resolve Kubernetes cluster API URL dns: lookup api.mycluster.example.com: no such host
// after
$ dig api.mycluster.example.com   # confirm the A record exists
$ kops validate cluster           # succeeds once DNS resolves
Defensive patterns

Strategy: retry

Validate before calling

_, err := net.LookupHost(hostFromURL(apiURL))
if err != nil {
    return fmt.Errorf("API host %s not resolvable yet: %v", hostFromURL(apiURL), err)
}

Try / catch

var ph string
err := retry.OnError(wait.Backoff{Steps: 6, Duration: 10 * time.Second},
    func(err error) bool { return isDNSTempFailure(err) },
    func() (err error) { ph, err = hasPlaceHolderIP(apiURL); return err })
if err != nil {
    return fmt.Errorf("API DNS still unresolvable: %w", err)
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/dab6757b06867535. Report an issue: GitHub.

Appendix: source

Thrown at pkg/validation/validate_cluster.go:101

// ValidationNode represents the validation status for a node
type ValidationNode struct {
	Name     string             `json:"name,omitempty"`
	Zone     string             `json:"zone,omitempty"`
	Role     string             `json:"role,omitempty"`
	Hostname string             `json:"hostname,omitempty"`
	Status   v1.ConditionStatus `json:"status,omitempty"`
}

// hasPlaceHolderIP checks if the API DNS has been updated.
func hasPlaceHolderIP(host string) (string, error) {
	apiAddr, err := url.Parse(host)
	if err != nil {
		return "", fmt.Errorf("unable to parse Kubernetes cluster API URL: %v", err)
	}
	hostAddrs, err := net.LookupHost(apiAddr.Hostname())
	if err != nil {
		return "", fmt.Errorf("unable to resolve Kubernetes cluster API URL dns: %v", err)
	}

	sort.Strings(hostAddrs)
	for _, h := range hostAddrs {
		if h == dns.PlaceholderIP || h == dns.PlaceholderIPv6 {
			return h, nil
		}
	}

	return "", nil
}

func 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) {
	var allInstanceGroups []*kops.InstanceGroup

	for i := range instanceGroupList.Items {
		ig := &instanceGroupList.Items[i]
		allInstanceGroups = append(allInstanceGroups, ig)

View on GitHub (pinned to 4c8573c808)