cilium/cilium · error

CIDR length must be in (0,128]

Error message

CIDR length must be in (0,128]

What it means

InitKubeProxyReplacementOptions validates --loadbalancer-rss-ipv6-cidr. After parsing the CIDR with net.ParseCIDR, it requires the prefix length to be strictly greater than 0 (and at most 128, which ParseCIDR already guarantees). A /0 mask is rejected because a zero-length RSS prefix is meaningless for source IP rewriting in kube-proxy-replacement mode.

Source

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

				if ones, _ := cidr.Mask.Size(); ones == 0 {
					err = fmt.Errorf("CIDR length must be in (0,32]")
				}
			}
			if err != nil {
				return fmt.Errorf("Invalid value for --%s: %s",
					option.LoadBalancerRSSv4CIDR, option.Config.LoadBalancerRSSv4CIDR)
			}
			option.Config.UnsafeDaemonConfigOption.LoadBalancerRSSv4 = *cidr
		}

		if option.Config.LoadBalancerRSSv6CIDR != "" {
			ip, cidr, err := net.ParseCIDR(option.Config.LoadBalancerRSSv6CIDR)
			if ip.To4() != nil {
				err = fmt.Errorf("CIDR is not IPv6 based")
			}
			if err == nil {
				if ones, _ := cidr.Mask.Size(); ones == 0 {
					err = fmt.Errorf("CIDR length must be in (0,128]")
				}
			}
			if err != nil {
				return fmt.Errorf("Invalid value for --%s: %s",
					option.LoadBalancerRSSv6CIDR, option.Config.LoadBalancerRSSv6CIDR)
			}
			option.Config.UnsafeDaemonConfigOption.LoadBalancerRSSv6 = *cidr
		}

		dsrIPIP := r.lbConfig.LoadBalancerUsesDSR() && r.lbConfig.DSRDispatch == loadbalancer.DSRDispatchIPIP
		if dsrIPIP {
			option.Config.UnsafeDaemonConfigOption.EnableIPIPDevices = true
			option.Config.EnableIPIPTermination = true
		}

		if (option.Config.LoadBalancerRSSv4CIDR != "" || option.Config.LoadBalancerRSSv6CIDR != "") && !dsrIPIP {
			return fmt.Errorf("Invalid value for --%s/%s: currently only supported under %s dispatch for DSR",
				option.LoadBalancerRSSv4CIDR, option.LoadBalancerRSSv6CIDR, loadbalancer.DSRDispatchIPIP)

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Set --loadbalancer-rss-ipv6-cidr to a specific IPv6 prefix with a non-zero length, e.g. fd00::/64.
  2. If RSS configuration is not needed, clear --loadbalancer-rss-ipv6-cidr entirely so the validation block is skipped.
  3. Note the error is reported as 'Invalid value for --loadbalancer-rss-ipv6-cidr: <value>' to the user; check the flag value.

Example fix

// before
--loadbalancer-rss-ipv6-cidr=::/0
// after
--loadbalancer-rss-ipv6-cidr=fd00:10::/64
Defensive patterns

Strategy: validation

Validate before calling

cidr := option.Config.LoadBalancerRSSv6CIDR
if cidr != "" {
	_, ipnet, err := net.ParseCIDR(cidr)
	if err != nil {
		return fmt.Errorf("bad --loadbalancer-rss-ipv6-cidr %q: %v", cidr, err)
	}
	if ones, _ := ipnet.Mask.Size(); ones == 0 {
		return fmt.Errorf("--loadbalancer-rss-ipv6-cidr %q has /0 prefix; must be in (0,128]", cidr)
	}
}

Prevention

When it happens

Trigger: Setting --loadbalancer-rss-ipv6-cidr to an IPv6 CIDR with prefix length 0 (e.g. ::/0); net.ParseCIDR succeeds and the address is IPv6, but cidr.Mask.Size() returns ones==0, producing this error.

Common situations: Operators leaving the flag at a default/placeholder of ::/0, or using a documentation example with ::/0, while enabling DSR with IPIP dispatch and RSS configuration.

Related errors


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