{"record":{"id":"dd5fc4e4d64f5d9b","repo":"kubernetes/kops","slug":"subnet-q-has-unexpected-cidr-q","errorCode":null,"errorMessage":"subnet %q has unexpected CIDR %q","messagePattern":"subnet %q has unexpected CIDR %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/subnets.go","lineNumber":161,"sourceCode":"\t\t\tif !cidr.Contains(cidrSubnet.IP) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tswitch subnet.Type {\n\t\tcase kops.SubnetTypeDualStack, kops.SubnetTypePublic, kops.SubnetTypePrivate:\n\t\t\tbigSubnets = append(bigSubnets, subnet)\n\n\t\tcase kops.SubnetTypeUtility:\n\t\t\tlittleSubnets = append(littleSubnets, subnet)\n\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"subnet %q has unknown type %q\", subnet.Name, subnet.Type)\n\t\t}\n\n\t\tif subnet.CIDR != \"\" {\n\t\t\t_, subnetCIDR, err := net.ParseCIDR(subnet.CIDR)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"subnet %q has unexpected CIDR %q\", subnet.Name, subnet.CIDR)\n\t\t\t}\n\n\t\t\treserved = append(reserved, subnetCIDR)\n\t\t}\n\t}\n\n\t// Assign a consistent order\n\tsort.Sort(ByZone(bigSubnets))\n\tsort.Sort(ByZone(littleSubnets))\n\n\t// Check how many subnet slices are needed\n\tcidrCount := len(bigSubnets)\n\tif len(littleSubnets) > 0 {\n\t\tcidrCount += 1\n\t}\n\tvar bigCIDRs []*net.IPNet\n\tif cidrCount <= 1 {\n\t\tbigCIDRs, err = subnet.SplitInto1(cidr)","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/subnets.go#L143-L179","documentation":"After classifying a subnet, kOps parses any user-specified subnet CIDR so it can reserve it against overlap with the parent NetworkCIDR. This error means the subnet's CIDR failed net.ParseCIDR — same parse failure family as error 3420, but raised on the later pass that collects reserved CIDRs.","triggerScenarios":"PerformAssignments invoked with a subnet that passes type validation but whose cidr field is an unparsable CIDR string, e.g. '10.0.0.0/' or 'banana'.","commonSituations":"Partially-edited cluster specs where a CIDR was truncated; templated manifests that emitted empty or malformed CIDRs; mixing IPv6 CIDRs into an IPv4 cluster's subnet list.","solutions":["Correct the malformed cidr value on the offending subnet to a valid CIDR within or carved from networkCIDR","Remove the cidr field to let kOps auto-assign a CIDR from the parent networkCIDR","Validate the manifest offline with a CIDR linter or `kops get cluster -o yaml` round-trip before applying"],"exampleFix":"// before\n- name: nodes\n  cidr: 10.0.2.0/\n// after\n- name: nodes\n  cidr: 10.0.2.0/24","handlingStrategy":"validation","validationCode":"for _, s := range subnets {\n\tif s.CIDR != \"\" {\n\t\tif _, _, err := net.ParseCIDR(s.CIDR); err != nil {\n\t\t\treturn fmt.Errorf(\"subnet %q CIDR %q invalid\", s.Name, s.CIDR)\n\t\t}\n\t}\n}","typeGuard":"func parseableCIDR(s string) bool {\n\t_, _, err := net.ParseCIDR(s)\n\treturn err == nil\n}","tryCatchPattern":"if err := PerformAssignments(c, cloud); err != nil {\n\tif strings.Contains(err.Error(), \"unexpected CIDR\") { /* fix the named subnet's CIDR */ }\n\treturn err\n}","preventionTips":["Include the /prefix in every subnet CIDR — a bare IP is not a CIDR","Validate IPv4 vs IPv6 consistency across the cluster spec","Lint manifests in CI with a CIDR checker before running kops update"],"tags":["network","cidr","validation","kops"],"backgroundTag":"invalid-cidr-notation","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"}