cilium/cilium · error

Unable to parse min port value %s for ephemeral range: %w

Error message

Unable to parse min port value %s for ephemeral range: %w

What it means

The first token of net.ipv4.ip_local_port_range (the ephemeral range minimum) could not be converted to an integer with strconv.Atoi. The message includes the offending token and the underlying parse error. This protects the NodePort-range-vs-ephemeral-range overlap logic from garbage input.

Source

Thrown at pkg/kpr/initializer/kube_proxy_replacement.go:380

// the same as a nodeport service.
//
// If it clashes, check whether the nodeport range is listed in ip_local_reserved_ports.
// If it isn't and EnableAutoProtectNodePortRange == false, then return an error
// making cilium-agent to stop.
// Otherwise, if EnableAutoProtectNodePortRange == true, then append the nodeport
// range to ip_local_reserved_ports.
func checkNodePortAndEphemeralPortRanges(lbConfig loadbalancer.Config, sysctl sysctl.Sysctl) error {
	ephemeralPortRangeStr, err := sysctl.Read([]string{"net", "ipv4", "ip_local_port_range"})
	if err != nil {
		return fmt.Errorf("Unable to read net.ipv4.ip_local_port_range: %w", err)
	}
	ephemeralPortRange := strings.Split(ephemeralPortRangeStr, "\t")
	if len(ephemeralPortRange) != 2 {
		return fmt.Errorf("Invalid ephemeral port range: %s", ephemeralPortRangeStr)
	}
	ephemeralPortMin, err := strconv.Atoi(ephemeralPortRange[0])
	if err != nil {
		return fmt.Errorf("Unable to parse min port value %s for ephemeral range: %w",
			ephemeralPortRange[0], err)
	}
	ephemeralPortMax, err := strconv.Atoi(ephemeralPortRange[1])
	if err != nil {
		return fmt.Errorf("Unable to parse max port value %s for ephemeral range: %w",
			ephemeralPortRange[1], err)
	}

	if lbConfig.NodePortMax < uint16(ephemeralPortMin) {
		// ephemeral port range does not clash with nodeport range
		return nil
	}

	nodePortRangeStr := fmt.Sprintf("%d-%d", lbConfig.NodePortMin,
		lbConfig.NodePortMax)

	if lbConfig.NodePortMin > uint16(ephemeralPortMax) {
		return fmt.Errorf("NodePort port range (%s) is not allowed to be after ephemeral port range (%s)",

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Fix the sysctl value to be two plain integers, e.g. sysctl -w net.ipv4.ip_local_port_range='32768 60999'
  2. Verify with cat /proc/sys/net/ipv4/ip_local_port_range that only two numbers appear
  3. Search the node's sysctl init scripts/configs (sysctl.d) for a malformed override and correct it

Example fix

# before
$ cat /etc/sysctl.d/99-ports.conf
net.ipv4.ip_local_port_range = 1024 65535 # keep low ports free
# after (comment must not be inline-parsed on some setups)
net.ipv4.ip_local_port_range = 1024 65535
Defensive patterns

Strategy: validation

Validate before calling

fields := strings.Fields(portRangeStr)
if len(fields) == 2 {
    if _, err := strconv.Atoi(fields[0]); err != nil {
        return fmt.Errorf("ephemeral min %q invalid", fields[0])
    }
    if _, err := strconv.Atoi(fields[1]); err != nil {
        return fmt.Errorf("ephemeral max %q invalid", fields[1])
    }
}

Try / catch

if err := agent.InitKubeProxyReplacementOptions(ctx); err != nil {
    if strings.Contains(err.Error(), "Unable to parse") && strings.Contains(err.Error(), "ephemeral range") {
        return fmt.Errorf("repair net.ipv4.ip_local_port_range (must be two integers) and restart agent: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: checkNodePortAndEphemeralPortRanges where ephemeralPortRange[0] contains non-numeric characters after the tab-split succeeded (e.g. leftover text, a digit-prefixed annotation, or locale-formatted number).

Common situations: Administrators manually editing ip_local_port_range with stray characters; scripted sysctl manipulation appending comments or units; kernels/shims exposing decorated sysctl values.

Understand the failure class

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/7cc2562445c85f43. Report an issue: GitHub.