k3s-io/k3s · error

incorrect netMode for flannel tailscale backend

Error message

incorrect netMode for flannel tailscale backend

What it means

The tailscale flannel backend builds its route advertisement list from the enabled IP families: $SUBNET for IPv4, $IPV6SUBNET for IPv6. If neither family is enabled the routes list is empty and the backend cannot function, so setup fails fast. netMode is derived from cluster-cidr, so this almost always means cluster-cidr contained no usable IPv4 or IPv6 CIDR.

Source

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

	}

	var backendConf string

	switch nodeConfig.Flannel.Backend {
	case BackendVXLAN:
		backendConf = vxlanBackend
	case BackendHostGW:
		backendConf = hostGWBackend
	case BackendTailscale:
		var routes []string
		if nm.IPv4Enabled() {
			routes = append(routes, "$SUBNET")
		}
		if nm.IPv6Enabled() {
			routes = append(routes, "$IPV6SUBNET")
		}
		if len(routes) == 0 {
			return errors.New("incorrect netMode for flannel tailscale backend")
		}
		advertisedRoutes, err := vpn.GetAdvertisedRoutes()
		if err == nil && advertisedRoutes != nil {
			for _, advertisedRoute := range advertisedRoutes {
				routes = append(routes, advertisedRoute.String())
			}
		}
		backendConf = strings.ReplaceAll(tailscaledBackend, "%Routes%", strings.Join(routes, ","))
	case BackendWireguardNative:
		backendConf = wireguardNativeBackend
	default:
		return fmt.Errorf("Cannot configure unknown flannel backend '%s'", nodeConfig.Flannel.Backend)
	}
	confJSON = strings.ReplaceAll(confJSON, "%backend%", backendConf)

	logrus.Debugf("The flannel configuration is %s", confJSON)
	return agentutil.WriteFile(nodeConfig.Flannel.ConfFile, confJSON)
}

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Set a valid --cluster-cidr with at least one IPv4 or IPv6 CIDR (e.g. --cluster-cidr=10.42.0.0/16) on the server and restart
  2. Check config.yaml on the node for a malformed cluster-cidr entry (missing mask, stray quotes/spaces)
  3. Ensure agents are not overriding cluster-cidr with an empty value

Example fix

# before
k3s server --flannel-backend=tailscale --cluster-cidr="" # -> incorrect netMode for flannel tailscale backend

# after
k3s server --flannel-backend=tailscale --cluster-cidr=10.42.0.0/16,fd01::/48
Defensive patterns

Strategy: validation

Validate before calling

func hasAnyFamily(cidrs []net.IPNet) bool {
    for _, c := range cidrs {
        if utilsnet.IsIPv4CIDR(c) || utilsnet.IsIPv6CIDR(c) { return true }
    }
    return false
}
if nodeConfig.Flannel.Backend == flannel.BackendTailscale && !hasAnyFamily(nodeConfig.AgentConfig.ClusterCIDRs) {
    return errors.New("tailscale backend requires an IPv4 or IPv6 cluster-cidr")
}

Prevention

When it happens

Trigger: Starting with --flannel-backend=tailscale while --cluster-cidr is empty, contains invalid CIDRs, or none parse as IPv4/IPv6 via utilsnet.IsIPv4CIDR/IsIPv6CIDR.

Common situations: Tailscale backend selected on a node where cluster-cidr was not set (e.g. mis-parsed config.yaml), or a custom CIDR string with a typo (e.g. 10.42.0.0/16 dropped mask) that slipped through earlier validation.

Related errors


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