kubernetes/kops · error

unable to determine IP address for kube-apiserver

Error message

unable to determine IP address for kube-apiserver

What it means

After enumerating ingress entries, GetWellKnownAddresses requires at least one IP address for the kube-apiserver. If the load balancer returned no usable ingress IPs, it fails with 'unable to determine IP address for kube-apiserver'. DNS-only hostnames are explicitly not supported here (see TODO).

Source

Thrown at pkg/commands/toolbox_enroll.go:743

	{
		ingresses, err := cloud.GetApiIngressStatus(fullCluster)
		if err != nil {
			return nil, fmt.Errorf("error getting ingress status: %v", err)
		}

		for _, ingress := range ingresses {
			// TODO: Do we need to support hostnames?
			// if ingress.Hostname != "" {
			// 	apiserverAdditionalIPs = append(apiserverAdditionalIPs, ingress.Hostname)
			// }
			if ingress.IP != "" {
				wellKnownAddresses[wellknownservices.KubeAPIServer] = append(wellKnownAddresses[wellknownservices.KubeAPIServer], ingress.IP)
			}
		}
	}
	if len(wellKnownAddresses[wellknownservices.KubeAPIServer]) == 0 {
		// TODO: Should we support DNS?
		return nil, fmt.Errorf("unable to determine IP address for kube-apiserver")
	}
	for k := range wellKnownAddresses {
		sort.Strings(wellKnownAddresses[k])
	}

	b.wellKnownAddresses = &wellKnownAddresses
	return wellKnownAddresses, nil
}

func (b *ConfigBuilder) GetBootstrapData(ctx context.Context) (*BootstrapData, error) {
	if b.bootstrapData != nil {
		return b.bootstrapData, nil
	}

	cluster, err := b.GetFullCluster(ctx)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the API load balancer has healthy targets and a static IP (prefer NLB with elastic IPs).
  2. Check `kops get cluster -oyaml` spec.api.loadBalancer settings; switch type to NLB so IPs are exposed.
  3. Wait until `kops validate cluster` reports the API endpoint reachable, then retry.
  4. If DNS is the only endpoint, this code path does not support it — provision an IP-based LB or extend the code to support hostnames.

Example fix

// before
// LB type: ClassicELB exposing only hostname -> no IPs collected
// after (cluster spec)
// spec:
//   api:
//     loadBalancer:
//       type: Network  # NLB provides resolvable static IPs
Defensive patterns

Strategy: validation

Validate before calling

// Verify the LB provides IP-type ingress before enrolling
// kops get cluster -oyaml | grep -A3 loadBalancer  -> expect type: Network (NLB)

Try / catch

if err != nil {
	if strings.Contains(err.Error(), "unable to determine IP address") {
		// fall back to checking the LB config; NLB with elastic IPs required
	}
	return err
}

Prevention

When it happens

Trigger: GetApiIngressStatus succeeded but every ingress entry has an empty IP (e.g. NLB with only a DNS hostname, or LB still initializing), leaving wellKnownAddresses[KubeAPIServer] empty.

Common situations: Classic ELB or ALB exposing only hostname rather than IP; load balancer just created and no healthy targets/attachments yet; cluster provisioned with a DNS-based API endpoint (spec.api.access or gossip/DNS misconfiguration).

Related errors


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