k3s-io/k3s · error

Failed checking netMode

Error message

Failed checking netMode

What it means

findNetMode inspects the cluster CIDR list to decide which IP families flannel must enable. Unless dualStack is pre-detected, it iterates the CIDRs and returns ipv4 or ipv6 for the first recognizable family; if no entry is a valid IPv4 or IPv6 CIDR it returns this error. It is a configuration-integrity check: the caller (flannel setup) treats it as fatal (logrus.Fatalf in createFlannelConf).

Source

Thrown at pkg/agent/flannel/setup.go:282

// fundNetMode returns the mode (ipv4, ipv6 or dual-stack) in which flannel is operating
func findNetMode(cidrs []*net.IPNet) (netMode, error) {
	dualStack, err := utilsnet.IsDualStackCIDRs(cidrs)
	if err != nil {
		return 0, err
	}
	if dualStack {
		return ipv4 | ipv6, nil
	}

	for _, cidr := range cidrs {
		if utilsnet.IsIPv4CIDR(cidr) {
			return ipv4, nil
		}
		if utilsnet.IsIPv6CIDR(cidr) {
			return ipv6, nil
		}
	}
	return 0, errors.New("Failed checking netMode")
}

func syncAnnotations(ctx context.Context, nodeConfig *config.Node, coreClient kubernetes.Interface) error {
	nodes := coreClient.CoreV1().Nodes()
	node, err := nodes.Get(ctx, nodeConfig.AgentConfig.NodeName, metav1.GetOptions{})
	if err != nil {
		return err
	}

	patch := util.NewPatchList()
	patcher := util.NewPatcher[*v1.Node](nodes)
	if nodeConfig.Flannel.ExternalIP {
		for _, ipAddress := range nodeConfig.AgentConfig.NodeExternalIPs {
			if utilsnet.IsIPv4(ipAddress) && node.Annotations[ExternalIPv4Annotation] != ipAddress.String() {
				patch.Add(ipAddress.String(), "metadata", "annotations", ExternalIPv4Annotation)
			}
			if utilsnet.IsIPv6(ipAddress) && node.Annotations[ExternalIPv6Annotation] != ipAddress.String() {
				patch.Add(ipAddress.String(), "metadata", "annotations", ExternalIPv6Annotation)

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Ensure --cluster-cidr is set to one or two valid CIDRs (IPv4 and optionally IPv6) before flannel setup runs
  2. Validate each CIDR with net/net.SplitHostPort-free parsing (netip.ParsePrefix) early in your tooling and reject empties
  3. Do not clear or replace AgentConfig.ClusterCIDRs after agent config validation has run

Example fix

// before
cidrs := []net.IPNet{} // empty
nm, err := findNetMode(cidrs) // -> Failed checking netMode

// after
_, n1, _ := net.ParseCIDR("10.42.0.0/16")
nm, err := findNetMode([]net.IPNet{*n1}) // ipv4
Defensive patterns

Strategy: validation

Validate before calling

for _, cidr := range nodeConfig.AgentConfig.ClusterCIDRs {
    if cidr.IP == nil || cidr.Mask == nil {
        return fmt.Errorf("invalid (empty) cluster CIDR entry; fix --cluster-cidr")
    }
}
nm, err := findNetMode(nodeConfig.AgentConfig.ClusterCIDRs) // now cannot hit the fallthrough

Prevention

When it happens

Trigger: nodeConfig.AgentConfig.ClusterCIDRs containing zero entries or entries that are neither IPv4 nor IPv6 CIDRs (e.g. zero-value net.IPNet or an unparsed string converted without validation); library callers constructing config.Node by hand.

Common situations: Custom embedding of the k3s agent that skips CIDR parsing/validation; tests with empty ClusterCIDRs; downstream tools mutating ClusterCIDRs after validation.

Related errors


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