{"record":{"id":"060b965adfc30162","repo":"kubernetes/kops","slug":"expected-exactly-one-subnet-with-gce-ip-aliases","errorCode":null,"errorMessage":"expected exactly one subnet with GCE IP Aliases","messagePattern":"expected exactly one subnet with GCE IP Aliases","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gce/network.go","lineNumber":156,"sourceCode":"\t\t\tcontinue\n\t\t}\n\t\tif err := used.MarkInUse(subnet.IpCidrRange); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tfor _, s := range subnet.SecondaryIpRanges {\n\t\t\tif err := used.MarkInUse(s.IpCidrRange); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn used, nil\n}\n\nfunc performNetworkAssignmentsIPAliases(ctx context.Context, c *kops.Cluster, cloudObj fi.Cloud) error {\n\tif len(c.Spec.Networking.Subnets) != 1 {\n\t\treturn fmt.Errorf(\"expected exactly one subnet with GCE IP Aliases\")\n\t}\n\tnodeSubnet := &c.Spec.Networking.Subnets[0]\n\n\tif c.Spec.Networking.PodCIDR != \"\" && c.Spec.Networking.ServiceClusterIPRange != \"\" && nodeSubnet.CIDR != \"\" {\n\t\treturn nil\n\t}\n\n\tused, err := buildUsed(ctx, c, cloudObj)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// CIDRs should be in the RFC1918 range, but otherwise we have no constraints\n\tnetworkCIDR := \"10.0.0.0/8\"\n\n\tpodCIDR, err := used.Allocate(networkCIDR, net.CIDRMask(14, 32))\n\tif err != nil {\n\t\treturn err","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gce/network.go#L138-L174","documentation":"performNetworkAssignmentsIPAliases implements kops GCE IP-alias networking under the assumption that the cluster uses exactly one subnet. If c.Spec.Networking.Subnets has a count other than 1, this error is thrown before any GCE API call. It is a hard design constraint of the GCE IP Aliases networking mode, not a cloud failure.","triggerScenarios":"Declaring GCE IP-alias networking (non-classic, UsesIPAliases true) in a cluster spec with zero subnets or with two or more subnets, during PerformNetworkAssignments at cluster creation/update.","commonSituations":"Multi-zone cluster specs where users add a subnet per region/zone; copying a multi-subnet AWS-style spec to GCE with ipalias networking enabled.","solutions":["Reduce spec.networking.subnets to exactly one subnet in the cluster spec","If multiple subnets are needed, switch to a networking mode that supports them (e.g. calico with multiple subnets where supported) or use GCE route-based networking","Check UsesIPAliases conditions: if you do not intend IP aliases, adjust networking config so classic mode is selected"],"exampleFix":"// before\nnetworking:\n  subnets:\n    - name: us-central1\n    - name: us-east1\n// after\nnetworking:\n  subnets:\n    - name: us-central1","handlingStrategy":"validation","validationCode":"if UsesIPAliases(cluster) && len(cluster.Spec.Networking.Subnets) != 1 {\n\treturn fmt.Errorf(\"GCE IP alias networking requires exactly one subnet, found %d\", len(cluster.Spec.Networking.Subnets))\n}","typeGuard":null,"tryCatchPattern":"err := gcecloud.PerformNetworkAssignments(ctx, cluster, cloud)\nif err != nil && strings.Contains(err.Error(), \"expected exactly one subnet\") {\n\treturn fmt.Errorf(\"cluster spec unsupported for GCE IP aliases: %w\", err)\n}","preventionTips":["Keep exactly one subnet when using GCE IP-alias networking","For multi-zone coverage, span the single subnet across the region instead of adding subnets","Lint cluster specs for subnet count before applying to GCE","If multi-subnet is a requirement, choose a networking mode that supports it"],"tags":["gce","ip-alias","networking","configuration"],"backgroundTag":"unsupported-multi-subnet-config","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"}