kubernetes/kops · error
error instance group cannot span public and private subnets
Error message
error instance group cannot span public and private subnets
What it means
Thrown by validateAllPrivateOrPublicSubnets during `kops toolbox instance-selector` subnet validation. It counts subnets prefixed with "utility-" (kOps public subnets) and rejects the request when the subnet list mixes utility (public) and non-utility (private) subnets, because an instance group spanning both public and private subnets is not a supported configuration.
Source
Thrown at cmd/kops/toolbox_instance-selector.go:489
}
if !userSubnetValid {
return fmt.Errorf("error subnets must exist in the cluster")
}
}
return nil
}
// validateAllPrivateOrPublicSubnets makes sure the passed in subnets are all utility (public) subnets or private subnets
func validateAllPrivateOrPublicSubnets(userSubnets []string) error {
utilitySubnets := 0
for _, userSubnet := range userSubnets {
if strings.HasPrefix(userSubnet, "utility-") {
utilitySubnets++
}
}
if utilitySubnets != 0 && len(userSubnets) != utilitySubnets {
return fmt.Errorf("error instance group cannot span public and private subnets")
}
return nil
}
func createInstanceGroup(groupName, clusterName string, subnets []string) *kops.InstanceGroup {
ig := &kops.InstanceGroup{}
ig.ObjectMeta.Name = groupName
ig.Spec.Role = kops.InstanceGroupRoleNode
ig.Spec.Subnets = subnets
ig.ObjectMeta.Labels = make(map[string]string)
ig.ObjectMeta.Labels[kops.LabelClusterName] = clusterName
ig.AddInstanceGroupNodeLabel()
return ig
}
func decorateWithInstanceGroupSpecs(instanceGroup *kops.InstanceGroup, instanceGroupOpts *InstanceSelectorOptions) *kops.InstanceGroup {
ig := instanceGroupView on GitHub (pinned to 4c8573c808)
Solutions
- Use only private subnets for the instance group: drop the utility- prefixed entries from --subnets
- Or use only utility- (public) subnets if the group truly must be public (rare for nodes; typical only for bastions)
- Check the cluster topology: `kops get cluster -o yaml` and match instance group subnets to one class of subnets
- For a public-facing role, create a separate instance group rather than mixing subnets in one group
Example fix
// before kops toolbox instance-selector --name nodes --subnets us-east-1a,utility-us-east-1b // after (private group) kops toolbox instance-selector --name nodes --subnets us-east-1a,us-east-1b
Defensive patterns
Strategy: validation
Validate before calling
utility := 0
for _, s := range requestedSubnets {
if strings.HasPrefix(s, "utility-") { utility++ }
}
if utility != 0 && utility != len(requestedSubnets) {
return fmt.Errorf("subnets mix public (utility-*) and private; pick one class")
} Prevention
- Decide group topology (public vs private) before writing subnet flags
- Never mix utility- prefixed and bare subnets in one instance group
- Name private subnets without the utility- prefix to keep the convention clear
- Derive subnet lists programmatically from the cluster spec filtered by prefix
When it happens
Trigger: Passing a --subnets list to `kops toolbox instance-selector` that contains at least one "utility-*" subnet and at least one subnet without the "utility-" prefix (e.g. --subnets us-east-1a,utility-us-east-1a).
Common situations: Mixing public and private subnets when defining node instance groups; assuming kOps will auto-route a group across both; generated scripts from a public cluster reused on a private-topology cluster (or vice versa); misunderstanding that the utility- prefix denotes public subnets.
Related errors
- error subnets must exist in the cluster
- found subnets of different types: %v
- control-plane InstanceGroup %s did not specify any Subnets
- unable to infer any Subnets for InstanceGroup %s
- invalid InstanceGroup name: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/d5f291ddfe250d57.
Report an issue: GitHub.