{"record":{"id":"e31bcb1eeee4c5d0","repo":"cilium/cilium","slug":"unable-to-parse-max-port-value-s-for-ephemeral-ra","errorCode":null,"errorMessage":"Unable to parse max port value %s for ephemeral range: %w","messagePattern":"Unable to parse max port value (.+?) for ephemeral range: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/kpr/initializer/kube_proxy_replacement.go","lineNumber":385,"sourceCode":"// Otherwise, if EnableAutoProtectNodePortRange == true, then append the nodeport\n// range to ip_local_reserved_ports.\nfunc checkNodePortAndEphemeralPortRanges(lbConfig loadbalancer.Config, sysctl sysctl.Sysctl) error {\n\tephemeralPortRangeStr, err := sysctl.Read([]string{\"net\", \"ipv4\", \"ip_local_port_range\"})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Unable to read net.ipv4.ip_local_port_range: %w\", err)\n\t}\n\tephemeralPortRange := strings.Split(ephemeralPortRangeStr, \"\\t\")\n\tif len(ephemeralPortRange) != 2 {\n\t\treturn fmt.Errorf(\"Invalid ephemeral port range: %s\", ephemeralPortRangeStr)\n\t}\n\tephemeralPortMin, err := strconv.Atoi(ephemeralPortRange[0])\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Unable to parse min port value %s for ephemeral range: %w\",\n\t\t\tephemeralPortRange[0], err)\n\t}\n\tephemeralPortMax, err := strconv.Atoi(ephemeralPortRange[1])\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Unable to parse max port value %s for ephemeral range: %w\",\n\t\t\tephemeralPortRange[1], err)\n\t}\n\n\tif lbConfig.NodePortMax < uint16(ephemeralPortMin) {\n\t\t// ephemeral port range does not clash with nodeport range\n\t\treturn nil\n\t}\n\n\tnodePortRangeStr := fmt.Sprintf(\"%d-%d\", lbConfig.NodePortMin,\n\t\tlbConfig.NodePortMax)\n\n\tif lbConfig.NodePortMin > uint16(ephemeralPortMax) {\n\t\treturn fmt.Errorf(\"NodePort port range (%s) is not allowed to be after ephemeral port range (%s)\",\n\t\t\tnodePortRangeStr, ephemeralPortRangeStr)\n\t}\n\n\treservedPortsStr, err := sysctl.Read([]string{\"net\", \"ipv4\", \"ip_local_reserved_ports\"})\n\tif err != nil {","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/kpr/initializer/kube_proxy_replacement.go#L367-L403","documentation":"During kube-proxy replacement initialization, Cilium reads /proc/sys/net/ipv4/ip_local_port_range (an \"MIN MAX\" string) and parses both bounds. This error means the second (max) value of the ephemeral port range could not be converted to an integer with strconv.Atoi. It wraps the underlying strconv parse error (%w) so the bad token and root cause are both visible.","triggerScenarios":"checkNodePortAndEphemeralPortRanges splits the value of net.ipv4.ip_local_port_range on whitespace and calls strconv.Atoi on ephemeralPortRange[1]; it fails when the kernel-side value is non-numeric, empty, or malformed (e.g. range file contents missing the max token).","commonSituations":"Corrupted or unusually formatted /proc/sys/net/ipv4/ip_local_port_range on a node; running in an environment (container, minimal OS) where the sysctl is empty or stubbed; a test harness providing a fake sysctl with a bad range string like \"32768 abc\".","solutions":["Read 'cat /proc/sys/net/ipv4/ip_local_port_range' and reset it with 'sysctl -w net.ipv4.ip_local_port_range=\"32768 60999\"' if malformed","Check the wrapped error and quoted value in the message to identify the non-numeric token","If in a container, ensure the host sysctl is visible/mounted and not overridden by an empty value"],"exampleFix":"// before (test fake sysctl)\nsysctl := mapsysctl.NewMapSysCtl(t, map[string]string{\"net/ipv4/ip_local_port_range\": \"32768 bogus\"})\n// after\nsysctl := mapsysctl.NewMapSysCtl(t, map[string]string{\"net/ipv4/ip_local_port_range\": \"32768 60999\"})","handlingStrategy":"validation","validationCode":"const ipLocalPortRange = \"/proc/sys/net/ipv4/ip_local_port_range\"\nb, err := os.ReadFile(ipLocalPortRange)\nif err != nil { return err }\nfields := strings.Fields(string(b))\nif len(fields) != 2 {\n    return fmt.Errorf(\"malformed %s: %q\", ipLocalPortRange, string(b))\n}\nfor _, f := range fields {\n    if _, err := strconv.Atoi(f); err != nil {\n        return fmt.Errorf(\"non-numeric token %q in %s: %w\", f, ipLocalPortRange, err)\n    }\n}","typeGuard":"func validPortRange(s string) bool {\n    fields := strings.Fields(s)\n    if len(fields) != 2 { return false }\n    _, err1 := strconv.Atoi(fields[0])\n    _, err2 := strconv.Atoi(fields[1])\n    return err1 == nil && err2 == nil\n}","tryCatchPattern":"if err := checkNodePortAndEphemeralPortRanges(lbConfig, sysctl); err != nil {\n    var numErr *strconv.NumError\n    if errors.As(err, &numErr) {\n        log.Fatalf(\"malformed ephemeral port range sysctl (bad token %q): fix net.ipv4.ip_local_port_range\", numErr.Num)\n    }\n    return err\n}","preventionTips":["Persist a known-good ip_local_port_range in /etc/sysctl.d/ on all nodes","Verify 'cat /proc/sys/net/ipv4/ip_local_port_range' outputs two integers before installing Cilium","In tests, always populate fake sysctl maps with realistic 'MIN MAX' strings"],"tags":["cilium","kube-proxy-replacement","sysctl","configuration"],"backgroundTag":"invalid-sysctl-port-range","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}