k3s-io/k3s · error

no IPv4 CIDRs found

Error message

no IPv4 CIDRs found

What it means

getFirst4Net in pkg/util/net.go scans a []*net.IPNet and returns the first IPv4 network; if every element is nil or has a nil To4() (IPv6-only or empty list) it returns 'no IPv4 CIDRs found'. Callers use it to derive the IPv4 service/cluster CIDR from flags like --service-cidr / --cluster-cidr, so the error surfaces at config parsing when no IPv4 range is available.

Source

Thrown at pkg/util/net.go:44

// JoinIPNets stringifies and joins a list of IP networks with commas.
func JoinIPNets(elems []*net.IPNet) string {
	var strs []string
	for _, elem := range elems {
		strs = append(strs, elem.String())
	}
	return strings.Join(strs, ",")
}

// getFirst4Net returns the first IPv4 network from the list of IP networks.
// If no IPv4 addresses are found, an error is raised.
func getFirst4Net(elems []*net.IPNet) (*net.IPNet, error) {
	for _, elem := range elems {
		if elem == nil || elem.IP.To4() == nil {
			continue
		}
		return elem, nil
	}
	return nil, errors.New("no IPv4 CIDRs found")
}

// getFirst4 returns the first IPv4 address from the list of IP addresses.
// If no IPv4 addresses are found, an error is raised.
func getFirst4(elems []net.IP) (net.IP, error) {
	for _, elem := range elems {
		if elem == nil || elem.To4() == nil {
			continue
		}
		return elem, nil
	}
	return nil, errors.New("no IPv4 address found")
}

// GetFirst4String returns the first IPv4 address from a list of IP address strings.
// If no IPv4 addresses are found, an error is raised.
func GetFirst4String(elems []string) (string, error) {
	ips := []net.IP{}

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Add an IPv4 CIDR to the relevant flag (e.g. --service-cidr=10.43.0.0/16,fd00:43::/112) so an IPv4 entry exists.
  2. If running IPv6-only, ensure the components invoked on this path actually support IPv6 and that their flags are set accordingly.
  3. Validate flags before start: each CIDR must parse via net.ParseCIDR and at least one must be IPv4 where required.

Example fix

# before: IPv6-only, IPv4-requiring path fails
k3s server --service-cidr=fd00:43::/112

# after: dual-stack list contains an IPv4 CIDR
k3s server --service-cidr=10.43.0.0/16,fd00:43::/112
Defensive patterns

Strategy: validation

Validate before calling

// Validate that at least one CIDR is IPv4 before config parsing
func hasIPv4CIDR(cidrs []string) bool {
    for _, c := range cidrs {
        _, n, err := net.ParseCIDR(c)
        if err == nil && n.IP.To4() != nil {
            return true
        }
    }
    return false
}

Try / catch

if err != nil && strings.Contains(err.Error(), "no IPv4 CIDRs found") {
    // add an IPv4 entry to --service-cidr/--cluster-cidr and restart
}

Prevention

When it happens

Trigger: Starting k3s (or calling the config helpers) with CIDR lists that contain only IPv6 ranges - e.g. --service-cidr=fd00:43::/112 with no IPv4 entry - while the code path being configured requires an IPv4 network (components without IPv6 support, or IPv4-mandatory settings).

Common situations: IPv6-only or dual-stack experiments; typos in CIDR flags; flags reordered so the first CIDR is v6 where a v4 is required.

Related errors


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