kubernetes/kops · error

could not determine any subnets for InstanceGroup %q; subnet

Error message

could not determine any subnets for InstanceGroup %q; subnets was %s

What it means

karpenterAssociatePublicIP resolves the subnets of a Karpenter-managed InstanceGroup to decide whether instances get a public IP. It calls GatherSubnets; when the result is empty it cannot classify the InstanceGroup, so it fails with this error. The error message includes the InstanceGroup name and its raw Spec.Subnets list for diagnosis.

Source

Thrown at upup/pkg/fi/cloudup/template_functions_karpenter.go:491

	}

	tokens := strings.SplitN(image, "/", 2)
	if len(tokens) == 1 {
		return []karpenterAMITerm{{Name: image, Owner: "self"}}, nil
	}
	if tokens[0] == "" || tokens[1] == "" {
		return nil, fmt.Errorf("image %q must be ami-*, ssm:<parameter>, <name>, or <owner>/<name>", image)
	}
	return []karpenterAMITerm{{Owner: awsup.ResolveImageOwnerAlias(tokens[0]), Name: tokens[1]}}, nil
}

func (tf *TemplateFunctions) karpenterAssociatePublicIP(ig *kops.InstanceGroup) (*bool, error) {
	subnets, err := tf.GatherSubnets(ig)
	if err != nil {
		return nil, err
	}
	if len(subnets) == 0 {
		return nil, fmt.Errorf("could not determine any subnets for InstanceGroup %q; subnets was %s", ig.Name, ig.Spec.Subnets)
	}

	switch subnets[0].Type {
	case kops.SubnetTypePublic, kops.SubnetTypeUtility:
		if ig.Spec.AssociatePublicIP != nil {
			return ig.Spec.AssociatePublicIP, nil
		}
		return new(true), nil
	case kops.SubnetTypeDualStack, kops.SubnetTypePrivate:
		return new(false), nil
	default:
		return nil, fmt.Errorf("unknown subnet type %q for InstanceGroup %q", subnets[0].Type, ig.Name)
	}
}

func (tf *TemplateFunctions) karpenterRequirements(ig *kops.InstanceGroup) []karpenterRequirement {
	requirements := []karpenterRequirement{
		{

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set spec.subnets on the InstanceGroup to valid cluster subnet names (e.g. `subnets: [us-east-1a]`) and re-run kops update.
  2. Verify the listed subnet names exist in the cluster spec (cluster.spec.subnets) and match exactly (name/zone).
  3. If the IG is auto-generated by Karpenter integration, ensure the cluster spec subnets are populated before applying.
  4. Run `kops get instancegroups` / `kops get cluster -o yaml` to confirm subnet wiring.

Example fix

// before
spec:
  subnets: []
// after
spec:
  subnets:
  - us-east-1a
Defensive patterns

Strategy: validation

Validate before calling

igName := ig.Name
if len(ig.Spec.Subnets) == 0 {
    return fmt.Errorf("instance group %q has no subnets; set spec.subnets to cluster subnet names", igName)
}

Type guard

func hasSubnets(ig *kops.InstanceGroup) bool {
    return ig != nil && len(ig.Spec.Subnets) > 0
}

Prevention

When it happens

Trigger: kOps apply/build of a cluster containing a Karpenter EC2NodeClass whose associated InstanceGroup has an empty (or effectively unresolvable) Spec.Subnets list, or subnets that GatherSubnets cannot match against the cluster's defined subnets.

Common situations: NodeTemplates/InstanceGroups created without a `subnets` field; subnets referencing names/zones not present in the cluster spec; Karpenter generated IGs that bypass normal subnet assignment; partial cluster configs migrated between kOps versions.

Related errors


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