{"record":{"id":"bf974f9fe4b663ed","repo":"cilium/cilium","slug":"invalid-reserved-range-end-q-in-pool-cidr-s-w","errorCode":null,"errorMessage":"invalid reserved range end %q in pool CIDR %s: %w","messagePattern":"invalid reserved range end %q in pool CIDR (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"operator/pkg/ipam/allocator/multipool/pool_handler.go","lineNumber":196,"sourceCode":"\t\t\tcidr:           prefix,\n\t\t\treservedRanges: reservedRanges,\n\t\t})\n\t}\n\n\treturn configs, nil\n}\n\nfunc parseReservedRanges(poolCIDR netip.Prefix, ranges []v2.ReservedRange) ([]netipx.IPRange, error) {\n\treserved := make([]netipx.IPRange, 0, len(ranges))\n\tfor _, rr := range ranges {\n\t\tstart, err := netip.ParseAddr(rr.Start)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid reserved range start %q in pool CIDR %s: %w\", rr.Start, poolCIDR, err)\n\t\t}\n\n\t\tend, err := netip.ParseAddr(rr.End)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid reserved range end %q in pool CIDR %s: %w\", rr.End, poolCIDR, err)\n\t\t}\n\n\t\tr := netipx.IPRangeFrom(start, end)\n\t\tif !r.IsValid() {\n\t\t\treturn nil, fmt.Errorf(\"invalid reserved range %s-%s in pool CIDR %s\", start, end, poolCIDR)\n\t\t}\n\n\t\tif !poolCIDR.Contains(start) || !poolCIDR.Contains(end) {\n\t\t\treturn nil, fmt.Errorf(\"reserved range %s-%s is outside pool CIDR %s\", start, end, poolCIDR)\n\t\t}\n\n\t\treserved = append(reserved, r)\n\t}\n\n\treturn reserved, nil\n}\n","sourceCodeStart":178,"sourceCodeEnd":213,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/operator/pkg/ipam/allocator/multipool/pool_handler.go#L178-L213","documentation":"parseReservedRanges could not parse the End field of a ReservedRange as an IP address via netip.ParseAddr. Mirrors the start-address failure but for the range's end value; the netip parse error is wrapped and both the value and pool CIDR are reported.","triggerScenarios":"A v2.ReservedRange in a pool's PoolCIDRConfig has rr.End that is not a valid IP literal: empty string, hostname, CIDR notation, out-of-family value for an IPv6 pool, or typographical error.","commonSituations":"Typos when reserving the last addresses of a range; copy-paste from IPv4 config into IPv6 pool; YAML indentation errors leaving End empty or shifted into another field.","solutions":["Correct rr.End to a valid bare IP literal in the same family as the pool CIDR.","Ensure the field is actually populated (check YAML structure/indentation).","Remove any prefix length or zone notation from the value.","Pre-validate with netip.ParseAddr in tooling or admission webhooks."],"exampleFix":"// before\nreservedRanges: [{start: \"10.0.0.240\", end: \"10.0.0.255/32\"}]\n// after\nreservedRanges: [{start: \"10.0.0.240\", end: \"10.0.0.255\"}]","handlingStrategy":"validation","validationCode":"for _, rr := range ranges {\n    if _, err := netip.ParseAddr(rr.End); err != nil {\n        return fmt.Errorf(\"ReservedRange.End %q is not a valid IP: %w\", rr.End, err)\n    }\n}","typeGuard":"func isValidEndIP(s string) bool {\n    _, err := netip.ParseAddr(s)\n    return err == nil && s != \"\"\n}","tryCatchPattern":"if _, err := netip.ParseAddr(rr.End); err != nil {\n    return fmt.Errorf(\"invalid reserved range end %q: use a bare IP literal\", rr.End)\n}","preventionTips":["Verify End is populated and matches the pool's address family.","Lint YAML structure so values do not shift between fields.","Copy ranges within the same family only."],"tags":["cilium","ipam","ip-parsing","config-validation"],"backgroundTag":"invalid-ip-address-format","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}