{"record":{"id":"227b5dd721f100aa","repo":"k3s-io/k3s","slug":"failed-checking-netmode","errorCode":null,"errorMessage":"Failed checking netMode","messagePattern":"Failed checking netMode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/agent/flannel/setup.go","lineNumber":282,"sourceCode":"// fundNetMode returns the mode (ipv4, ipv6 or dual-stack) in which flannel is operating\nfunc findNetMode(cidrs []*net.IPNet) (netMode, error) {\n\tdualStack, err := utilsnet.IsDualStackCIDRs(cidrs)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif dualStack {\n\t\treturn ipv4 | ipv6, nil\n\t}\n\n\tfor _, cidr := range cidrs {\n\t\tif utilsnet.IsIPv4CIDR(cidr) {\n\t\t\treturn ipv4, nil\n\t\t}\n\t\tif utilsnet.IsIPv6CIDR(cidr) {\n\t\t\treturn ipv6, nil\n\t\t}\n\t}\n\treturn 0, errors.New(\"Failed checking netMode\")\n}\n\nfunc syncAnnotations(ctx context.Context, nodeConfig *config.Node, coreClient kubernetes.Interface) error {\n\tnodes := coreClient.CoreV1().Nodes()\n\tnode, err := nodes.Get(ctx, nodeConfig.AgentConfig.NodeName, metav1.GetOptions{})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tpatch := util.NewPatchList()\n\tpatcher := util.NewPatcher[*v1.Node](nodes)\n\tif nodeConfig.Flannel.ExternalIP {\n\t\tfor _, ipAddress := range nodeConfig.AgentConfig.NodeExternalIPs {\n\t\t\tif utilsnet.IsIPv4(ipAddress) && node.Annotations[ExternalIPv4Annotation] != ipAddress.String() {\n\t\t\t\tpatch.Add(ipAddress.String(), \"metadata\", \"annotations\", ExternalIPv4Annotation)\n\t\t\t}\n\t\t\tif utilsnet.IsIPv6(ipAddress) && node.Annotations[ExternalIPv6Annotation] != ipAddress.String() {\n\t\t\t\tpatch.Add(ipAddress.String(), \"metadata\", \"annotations\", ExternalIPv6Annotation)","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/agent/flannel/setup.go#L264-L300","documentation":"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).","triggerScenarios":"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.","commonSituations":"Custom embedding of the k3s agent that skips CIDR parsing/validation; tests with empty ClusterCIDRs; downstream tools mutating ClusterCIDRs after validation.","solutions":["Ensure --cluster-cidr is set to one or two valid CIDRs (IPv4 and optionally IPv6) before flannel setup runs","Validate each CIDR with net/net.SplitHostPort-free parsing (netip.ParsePrefix) early in your tooling and reject empties","Do not clear or replace AgentConfig.ClusterCIDRs after agent config validation has run"],"exampleFix":"// before\ncidrs := []net.IPNet{} // empty\nnm, err := findNetMode(cidrs) // -> Failed checking netMode\n\n// after\n_, n1, _ := net.ParseCIDR(\"10.42.0.0/16\")\nnm, err := findNetMode([]net.IPNet{*n1}) // ipv4","handlingStrategy":"validation","validationCode":"for _, cidr := range nodeConfig.AgentConfig.ClusterCIDRs {\n    if cidr.IP == nil || cidr.Mask == nil {\n        return fmt.Errorf(\"invalid (empty) cluster CIDR entry; fix --cluster-cidr\")\n    }\n}\nnm, err := findNetMode(nodeConfig.AgentConfig.ClusterCIDRs) // now cannot hit the fallthrough","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Parse and validate every CIDR with netip.ParsePrefix at config-load time","Reject empty ClusterCIDRs slices before calling flannel setup","In embedded tooling, never mutate ClusterCIDRs after validation"],"tags":["flannel","cidr","validation","internal-api"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}