{"record":{"id":"2f5991522c3f9c98","repo":"kubernetes/kops","slug":"found-multiple-subnets-with-name-q","errorCode":null,"errorMessage":"found multiple subnets with name: %q","messagePattern":"found multiple subnets with name: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/context.go","lineNumber":87,"sourceCode":"\n// GatherSubnets maps the subnet names in an InstanceGroup to the ClusterSubnetSpec objects (which are stored on the Cluster)\nfunc (b *KopsModelContext) GatherSubnets(ig *kops.InstanceGroup) ([]*kops.ClusterSubnetSpec, error) {\n\tvar subnets []*kops.ClusterSubnetSpec\n\tvar subnetType kops.SubnetType\n\n\tfor _, subnetName := range ig.Spec.Subnets {\n\t\tvar matches []*kops.ClusterSubnetSpec\n\t\tfor i := range b.Cluster.Spec.Networking.Subnets {\n\t\t\tclusterSubnet := &b.Cluster.Spec.Networking.Subnets[i]\n\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)","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/context.go#L69-L105","documentation":"This error is thrown by NodeupModelContext.FindSubnets (pkg/model/context.go:87) when resolving an InstanceGroup's subnet names to actual cluster Subnet specs. kOps looks up each configured subnet by name in the cluster spec and requires an exact, unique match; more than one Subnet sharing the same name is ambiguous, so the build aborts rather than guessing. It indicates a malformed cluster spec, since kOps normally prevents duplicate subnet names.","triggerScenarios":"Calling FindSubnets with a subnetName that matches more than one entry in b.Cluster.Spec.Subnets — e.g. a hand-edited or merged cluster.yaml where two subnet entries got the same 'name' field, or programmatic spec manipulation that appended duplicate subnet definitions.","commonSituations":"Manual editing of the cluster spec, YAML merge tooling or 'kops replace' with a spec that duplicated a subnet block, copy-pasting a subnet entry for a second zone without renaming it, or importing/templating cluster configs across environments.","solutions":["Run 'kops get cluster -o yaml' and inspect spec.subnets for two entries with the same name; rename one to a unique name","If the duplicate was unintentional, delete the redundant subnet entry with 'kops edit cluster' (or edit the manifest) and keep the one that matches the IG's spec.subnets reference","Ensure each instanceGroup's spec.subnets only references names that exist exactly once in the cluster spec","Update kOps if a bug in spec migration produced duplicates; re-export the cluster spec"],"exampleFix":"// before (cluster spec yaml)\nsubnets:\n- name: us-east-1a\n  zone: us-east-1a\n  type: Public\n- name: us-east-1a\n  zone: us-east-1b\n  type: Public\n// after\nsubnets:\n- name: us-east-1a\n  zone: us-east-1a\n  type: Public\n- name: us-east-1b\n  zone: us-east-1b\n  type: Public","handlingStrategy":"validation","validationCode":"// Go: before rendering the model, ensure each referenced subnet name is unique\nfunc validateUniqueSubnetNames(cluster *kops.Cluster) error {\n\tseen := map[string]int{}\n\tfor _, s := range cluster.Spec.Subnets {\n\t\tif prev, dup := seen[s.Name]; dup {\n\t\t\treturn fmt.Errorf(\"subnet name %q used at indexes %d and %d\", s.Name, prev, dup)\n\t\t}\n\t\tseen[s.Name] = 1\n\t}\n\treturn nil\n}","typeGuard":"func hasUniqueSubnetNames(subnets []kops.ClusterSubnetSpec) bool {\n\tseen := map[string]bool{}\n\tfor _, s := range subnets {\n\t\tif seen[s.Name] { return false }\n\t\tseen[s.Name] = true\n\t}\n\treturn true\n}","tryCatchPattern":null,"preventionTips":["Always edit subnets via 'kops edit cluster' rather than raw YAML merges","Run 'kops validate cluster' / dry-run update after spec changes","Template renders of cluster specs should assert subnet name uniqueness","Never copy-paste a subnet entry without renaming it"],"tags":["kops","cluster-spec","subnets","configuration"],"backgroundTag":"ambiguous-subnet-name","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"}