kubernetes/kops · error

instance %q has no private IPv4 address

Error message

instance %q has no private IPv4 address

What it means

When UseIPBasedNodeNames is enabled, kOps derives the node's name from the instance's primary private IPv4 address (via PrivateDNSName) so issued certificates match exactly what nodeup registers, independent of VPC DNS settings. If the instance has no PrivateIpAddress set, that name cannot be derived and the verifier fails rather than issuing a certificate for a mismatched node name.

Source

Thrown at pkg/bootstrap/awsbootstrap/verifier.go:343

		for _, a := range nic.Ipv6Addresses {
			if ip := aws.ToString(a.Ipv6Address); ip != "" {
				challengeEndpoints = append(challengeEndpoints, net.JoinHostPort(ip, strconv.Itoa(wellknownports.NodeupChallenge)))
			}
		}
	}

	if len(challengeEndpoints) == 0 {
		return nil, fmt.Errorf("cannot determine challenge endpoint for instance id: %s", instanceID)
	}

	nodeName := addrs[0]
	if a.opt.UseIPBasedNodeNames {
		// Derive the node name with the same formula nodeup uses, so that the certificates are
		// issued for the exact name the node registers with, whatever the VPC DNS configuration.
		privateIPv4 := aws.ToString(instance.PrivateIpAddress)
		if privateIPv4 == "" {
			return nil, fmt.Errorf("instance %q has no private IPv4 address", instanceID)
		}
		nodeName = PrivateDNSName(privateIPv4, a.opt.Region)
		if !slices.Contains(addrs, nodeName) {
			addrs = append(addrs, nodeName)
		}
	}

	result := &bootstrap.VerifyResult{
		NodeName:          nodeName,
		CertificateNames:  addrs,
		ChallengeEndpoint: challengeEndpoints[0],
	}

	for _, tag := range instance.Tags {
		tagKey := aws.ToString(tag.Key)
		if tagKey == cloudTagInstanceGroupName {
			result.InstanceGroupName = aws.ToString(tag.Value)
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure the instance has a primary private IPv4 address on its main ENI; IPv6-only instances are not supported by this code path.
  2. Retry after the instance finishes initializing if it was captured mid-setup.
  3. Disable UseIPBasedNodeNames if your environment relies on IPv6-only or DNS-based node naming, so names come from GetInstanceCertificateNames instead.
  4. Verify VPC/ENI settings in AWS so the primary network interface always carries a private IPv4.

Example fix

// Cluster spec change for IPv6-only environments:
// before
kubelet:
  ...
spec:
  useIPBasedNodeNames: true
// after
spec:
  useIPBasedNodeNames: false
Defensive patterns

Strategy: validation

Validate before calling

out, _ := ec2Client.DescribeInstances(ctx, &ec2.DescribeInstancesInput{InstanceIds: []string{instanceID}})
inst, ok := exactlyOneInstance(out)
if !ok { return fmt.Errorf("instance %s not found", instanceID) }
if useIPBasedNodeNames && aws.ToString(inst.PrivateIpAddress) == "" {
  return fmt.Errorf("instance %s lacks private IPv4 required by useIPBasedNodeNames", instanceID)
}

Type guard

func supportsIPBasedNodeNames(inst types.Instance) bool {
  return aws.ToString(inst.PrivateIpAddress) != ""
}

Try / catch

result, err := verifier.VerifyToken(ctx, token)
if err != nil && strings.Contains(err.Error(), "has no private IPv4 address") {
  return nil, fmt.Errorf("node cannot bootstrap: useIPBasedNodeNames requires a private IPv4; disable it or fix ENI config: %w", err)
}

Prevention

When it happens

Trigger: verifyCallerIdentity (via verifyTokenV1/verifyTokenV2) runs with a.opt.UseIPBasedNodeNames=true and aws.ToString(instance.PrivateIpAddress) returns "" for the verified instance.

Common situations: Clusters configured with UseIPBasedNodeNames where the instance's primary ENI lacks a private IPv4 (IPv6-only setup, odd ENI state, or instance mid-initialization); mixed IPv6-only configurations that this name-derivation path doesn't support.

Related errors


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