{"record":{"id":"d5fd62c68b7f7591","repo":"kubernetes/kops","slug":"found-subnets-of-different-types-v","errorCode":null,"errorMessage":"found subnets of different types: %v","messagePattern":"found subnets of different types: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/context.go","lineNumber":97,"sourceCode":"\t\t\tif clusterSubnet.Name == subnetName {\n\t\t\t\tmatches = append(matches, clusterSubnet)\n\t\t\t}\n\t\t}\n\t\tif len(matches) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"subnet not found: %q\", subnetName)\n\t\t}\n\t\tif len(matches) > 1 {\n\t\t\treturn nil, fmt.Errorf(\"found multiple subnets with name: %q\", subnetName)\n\t\t}\n\t\tsubnets = append(subnets, matches[0])\n\n\t\t// @step: check the instance is not cross subnet types\n\t\tswitch subnetType {\n\t\tcase \"\":\n\t\t\tsubnetType = matches[0].Type\n\t\tdefault:\n\t\t\tif matches[0].Type != subnetType {\n\t\t\t\treturn nil, fmt.Errorf(\"found subnets of different types: %v\", strings.Join([]string{string(subnetType), string(matches[0].Type)}, \",\"))\n\t\t\t}\n\t\t}\n\t}\n\n\treturn subnets, nil\n}\n\n// FindInstanceGroup returns the instance group with the matching Name (or nil if not found)\nfunc (b *KopsModelContext) FindInstanceGroup(name string) *kops.InstanceGroup {\n\tfor _, ig := range b.AllInstanceGroups {\n\t\tif ig.ObjectMeta.Name == name {\n\t\t\treturn ig\n\t\t}\n\t}\n\treturn nil\n}\n\n// FindSubnet returns the subnet with the matching Name (or nil if not found)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/context.go#L79-L115","documentation":"Thrown by NodeupModelContext.Init / FindSubnets (pkg/model/context.go:97) when the subnets selected for an InstanceGroup mix subnet Types (e.g. Public and Private, or DualStack vs others). An instance group's subnets must all be the same type because node provisioning (elastic IPs vs internal addresses, routing, etc.) depends on a single consistent subnet type. The message joins the two conflicting types.","triggerScenarios":"An InstanceGroup's spec.subnets resolves to subnets whose kops.SubnetType values differ — e.g. an IG listing both a 'utility' (Public) and a 'private' subnet, or a cluster upgraded to a new topology where one subnet's type was changed but the IG still references the old one.","commonSituations":"Converting a cluster from all-public to private topology and forgetting to update instance groups; renaming subnets so an IG accidentally references both public utility and private subnets; copy-pasted IG definitions across clusters with different topologies.","solutions":["Edit the cluster (kops edit cluster / manifest) so the instance group references only subnets of one type","If the node should be private, point the IG at the private subnets only; if public/utility, point it at the public subnets only","Verify each subnet's 'type' field is what you intend (Public/Private/DualStack) and that IG subnet lists were not mixed during a topology migration","Run 'kops update cluster --target dry-run' after the edit to confirm the model builds cleanly"],"exampleFix":"// before (instance group spec)\nsubnets: [us-east-1a, us-east-1a-private]\n// after\nsubnets: [us-east-1a-private]","handlingStrategy":"validation","validationCode":"func validateUniformSubnetTypes(cluster *kops.Cluster, ig *kops.InstanceGroup) error {\n\tbyName := map[string]kops.SubnetType{}\n\tfor _, s := range cluster.Spec.Subnets { byName[s.Name] = s.Type }\n\tvar first kops.SubnetType\n\tfor i, name := range ig.Spec.Subnets {\n\t\tt := byName[name]\n\t\tif i == 0 { first = t; continue }\n\t\tif t != first { return fmt.Errorf(\"IG %q mixes subnet types %v and %v\", ig.Name, first, t) }\n\t}\n\treturn nil\n}","typeGuard":"func uniformSubnetTypes(names []string, byName map[string]kops.SubnetType) bool {\n\tfor _, t := range typesOf(names, byName) {\n\t\tif t != typesOf(names, byName)[0] { return false }\n\t}\n\treturn true\n}","tryCatchPattern":null,"preventionTips":["Keep public IGs on utility/public subnets and private IGs on private subnets only","After a topology migration, grep IG specs for old subnet names","Run 'kops update cluster --target dry-run' before applying","Document each subnet's type in your cluster templating tooling"],"tags":["kops","subnets","instance-group","topology"],"backgroundTag":"mixed-subnet-types","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}