{"record":{"id":"f45dfb3882e7f5b8","repo":"kubernetes/kops","slug":"expected-exactly-one-subnet-for-instancegroup-q-f45dfb","errorCode":null,"errorMessage":"expected exactly one subnet for InstanceGroup %q; subnets was %s","messagePattern":"expected exactly one subnet for InstanceGroup %q; subnets was (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/azuremodel/vmscaleset.go","lineNumber":156,"sourceCode":"\t}\n\n\tif n := len(b.SSHPublicKeys); n > 0 {\n\t\tif n > 1 {\n\t\t\treturn nil, fmt.Errorf(\"expected at most one SSH public key; found %d keys\", n)\n\t\t}\n\t\tt.SSHPublicKey = new(string(b.SSHPublicKeys[0]))\n\t}\n\n\tif t.UserData, err = b.BootstrapScriptBuilder.ResourceNodeUp(c, ig); err != nil {\n\t\treturn nil, err\n\t}\n\n\tsubnets, err := b.GatherSubnets(ig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(subnets) != 1 {\n\t\treturn nil, fmt.Errorf(\"expected exactly one subnet for InstanceGroup %q; subnets was %s\", ig.Name, ig.Spec.Subnets)\n\t}\n\tsubnet := subnets[0]\n\tt.Subnet = b.LinkToAzureSubnet(subnet)\n\n\tswitch subnet.Type {\n\tcase kops.SubnetTypePublic, kops.SubnetTypeUtility:\n\t\tt.RequirePublicIP = new(true)\n\t\tif ig.Spec.AssociatePublicIP != nil {\n\t\t\tt.RequirePublicIP = ig.Spec.AssociatePublicIP\n\t\t}\n\tcase kops.SubnetTypeDualStack, kops.SubnetTypePrivate:\n\t\tt.RequirePublicIP = new(false)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected subnet type: for InstanceGroup %q; type was %s\", ig.Name, subnet.Type)\n\t}\n\n\tif ig.Spec.Role.HasControlPlane() && b.Cluster.Spec.API.LoadBalancer != nil {\n\t\tt.LoadBalancer = &azuretasks.LoadBalancer{","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/azuremodel/vmscaleset.go#L138-L174","documentation":"During Azure VM ScaleSet model building, kops resolves the subnets of an InstanceGroup via GatherSubnets and requires exactly one, because an Azure VM ScaleSet can only be placed in a single subnet. If the instance group's spec lists zero or multiple subnets, buildVMScaleSetTask refuses to continue with this error.","triggerScenarios":"Running `kops update cluster` (or building the Azure model) with an InstanceGroup whose spec.subnets contains 0 or more than 1 subnet names on an Azure cluster.","commonSituations":"Copying an AWS instance group config (which supports multiple subnets) to Azure; forgetting to define subnets; typos duplicated in the subnets list; multi-AZ configs pasted from AWS/GCP examples.","solutions":["Edit the InstanceGroup so spec.subnets contains exactly one subnet name, then run `kops update cluster --yes`.","If multi-AZ is desired on Azure, create one InstanceGroup per subnet/zone instead of listing multiple subnets in one group.","Verify the referenced subnet names exist in the cluster spec (spec.subnets) and match the cluster's topology."],"exampleFix":"// before (instancegroup nodes)\nsubnets:\n- subnet-a\n- subnet-b\n// after\nsubnets:\n- subnet-a","handlingStrategy":"validation","validationCode":"ig := cluster.InstanceGroup(\"nodes\")\nif ig != nil && len(ig.Spec.Subnets) != 1 {\n  return fmt.Errorf(\"azure instance group %q must list exactly one subnet, got %d\", ig.Name, len(ig.Spec.Subnets))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep one InstanceGroup per subnet on Azure clusters.","Never copy AWS multi-subnet instance group specs to Azure.","Lint cluster.yaml so every Azure InstanceGroup has exactly one entry under spec.subnets."],"tags":["azure","instancegroup","subnet","vmss"],"backgroundTag":"multiple-subnets-not-supported","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}