k3s-io/k3s · error

host identifier bits must not be set in CIDR prefix

Error message

host identifier bits must not be set in CIDR prefix

What it means

parseCIDR parses a CIDR with net.ParseCIDR and requires the parsed IP to equal the network address of the enclosing net.IPNet (ip.Equal(ipnet.IP)). Any prefix with host bits set - e.g. 10.0.0.5/16 instead of 10.0.0.0/16 - is rejected so downstream address allocation gets a clean base network.

Source

Thrown at pkg/rootless/rootless.go:128

func readSysctl(key string) (string, error) {
	p := "/proc/sys/" + strings.ReplaceAll(key, ".", "/")
	b, err := os.ReadFile(p)
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(b)), nil
}

func parseCIDR(s string) (*net.IPNet, error) {
	if s == "" {
		return nil, nil
	}
	ip, ipnet, err := net.ParseCIDR(s)
	if err != nil {
		return nil, err
	}
	if !ip.Equal(ipnet.IP) {
		return nil, errors.New("host identifier bits must not be set in CIDR prefix")
	}
	return ipnet, nil
}

func createParentOpt(driver portDriver, stateDir string, enableIPv6 bool) (*parent.Opt, error) {
	if err := os.MkdirAll(stateDir, 0755); err != nil {
		return nil, errors.WithMessagef(err, "failed to mkdir %s", stateDir)
	}

	driver.SetStateDir(stateDir)

	opt := &parent.Opt{
		StateDir:       stateDir,
		CreatePIDNS:    true,
		CreateCgroupNS: true,
		CreateUTSNS:    true,
		CreateIPCNS:    true,
	}

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Change the CIDR to its base network: 10.42.0.5/24 -> 10.42.0.0/24, fd00::1/64 -> fd00::/64.
  2. Compute it if generated programmatically: ip, ipnet, _ := net.ParseCIDR(s); use ipnet.String().
  3. Validate with 'ipcalc' or equivalent before deploying.

Example fix

// before
subnet := "192.168.5.1/24" // host bits set -> error
// after
subnet := "192.168.5.0/24"
Defensive patterns

Strategy: validation

Validate before calling

func isBaseCIDR(s string) bool {
	ip, ipnet, err := net.ParseCIDR(s)
	if err != nil {
		return false
	}
	return ip.Equal(ipnet.IP)
}

// normalize instead of rejecting:
ip, ipnet, err := net.ParseCIDR(s)
if err == nil {
    s = ipnet.String() // 10.0.0.5/16 -> 10.0.0.0/16
}

Prevention

When it happens

Trigger: Configuring rootless networking options that accept CIDRs (service/bridge CIDRs) with a host-portion-bearing address; passing an address like fd00::1/64 where fd00::/64 is required.

Common situations: Operators writing the gateway/node IP instead of the network address; copy-pasting pod CIDRs from another system that allows host bits; IPv6 configs where the interface identifier is left in.

Related errors


AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15). Data as JSON: /api/errors/f05bc5d974365a2e. Report an issue: GitHub.