{"record":{"id":"5118e8764ed7f121","repo":"kubernetes/kops","slug":"unable-to-parse-cidr-for-q-v","errorCode":null,"errorMessage":"unable to parse CIDR for %q: %v","messagePattern":"unable to parse CIDR for %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/utils/net.go","lineNumber":107,"sourceCode":"\tif err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"unable to convert CIDR subnet new bits to int: %q: %v\", s[1], err)\n\t}\n\n\tnetNum, err := strconv.ParseInt(s[2], 16, 64)\n\tif err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"unable to convert CIDR subnet net num to int: %q: %v\", s[2], err)\n\t}\n\n\treturn newSize, netNum, nil\n}\n\n// CIDRSubnet calculates a subnet address within given IP network address prefix.\n// Inspired by the Terraform implementation of the \"cidrsubnet\" function\n// https://www.terraform.io/docs/language/functions/cidrsubnet.html\nfunc CIDRSubnet(prefix string, newSize int, netNum int64) (string, error) {\n\t_, baseCIDR, err := net.ParseCIDR(prefix)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to parse CIDR for %q: %v\", prefix, err)\n\t}\n\n\toldSize, totalSize := baseCIDR.Mask.Size()\n\tif oldSize == 0 && totalSize == 0 {\n\t\treturn \"\", fmt.Errorf(\"unable to calculate CIDR mask size for %q: %q\", prefix, baseCIDR.Mask)\n\t}\n\n\tnewNetwork, err := cidr.SubnetBig(baseCIDR, newSize-oldSize, big.NewInt(netNum))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to calculate subnet CIDR for %q -> /%d#%d : %v\", prefix, newSize, netNum, err)\n\t}\n\n\treturn newNetwork.String(), nil\n}\n","sourceCodeStart":89,"sourceCodeEnd":122,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/utils/net.go#L89-L122","documentation":"CIDRSubnet computes a subnet address within a given IP network prefix (Terraform cidrsubnet-style). It first parses the base prefix with net.ParseCIDR; if the prefix is not valid CIDR syntax, the parse error is wrapped as this error and returned.","triggerScenarios":"Calling CIDRSubnet (via calculateSubnetCIDR) with a prefix string that net.ParseCIDR rejects: missing '/' and mask size (\"10.0.0.0\"), invalid octets (\"300.0.0.0/8\"), host bits set incorrectly, or non-IP text.","commonSituations":"Cluster spec networkCIDR/nonMasqueradeCIDR values hand-edited to omit the /mask; region or env-config substitution producing an empty string; mixing IPv6 shorthand with the IPv4-only expectation.","solutions":["Fix the prefix to include a valid mask, e.g. \"10.0.0.0/16\" instead of \"10.0.0.0\".","Verify each address component is a valid IP (octets 0-255 for IPv4).","Check that config/template substitution did not leave the prefix empty or malformed.","Pre-validate with net.ParseCIDR(prefix) in the caller and log a clear config error."],"exampleFix":"// before\nsubnet, err := utils.CIDRSubnet(\"172.20.0.0\", 8, 1) // missing /mask\n// after\nsubnet, err := utils.CIDRSubnet(\"172.20.0.0/16\", 8, 1)","handlingStrategy":"validation","validationCode":"func validCIDRPrefix(prefix string) error {\n\t_, _, err := net.ParseCIDR(prefix)\n\treturn err\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include the /mask in CIDR strings stored in cluster config.","Run `kops validate cluster` / config validation after hand-editing networkCIDR values.","Pre-check any external CIDR input with net.ParseCIDR before passing to helpers."],"tags":["network","cidr","parsing","subnet"],"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"}