{"record":{"id":"2ea81d45e3e44bba","repo":"k3s-io/k3s","slug":"no-ipv6-address-found","errorCode":null,"errorMessage":"no IPv6 address found","messagePattern":"no IPv6 address found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/util/net.go","lineNumber":94,"sourceCode":"func JoinIP4Nets(elems []*net.IPNet) string {\n\tvar strs []string\n\tfor _, elem := range elems {\n\t\tif elem != nil && elem.IP.To4() != nil {\n\t\t\tstrs = append(strs, elem.String())\n\t\t}\n\t}\n\treturn strings.Join(strs, \",\")\n}\n\n// getFirst6 returns the first IPv6 address from the list of IP addresses.\n// If no IPv6 addresses are found, an error is raised.\nfunc getFirst6(elems []net.IP) (net.IP, error) {\n\tfor _, elem := range elems {\n\t\tif elem != nil && netutils.IsIPv6(elem) {\n\t\t\treturn elem, nil\n\t\t}\n\t}\n\treturn nil, errors.New(\"no IPv6 address found\")\n}\n\n// getFirst6Net returns the first IPv4 network from the list of IP networks.\n// If no IPv6 addresses are found, an error is raised.\nfunc getFirst6Net(elems []*net.IPNet) (*net.IPNet, error) {\n\tfor _, elem := range elems {\n\t\tif elem != nil && netutils.IsIPv6(elem.IP) {\n\t\t\treturn elem, nil\n\t\t}\n\t}\n\treturn nil, errors.New(\"no IPv6 CIDRs found\")\n}\n\n// GetFirst6String returns the first IPv6 address from a list of IP address strings.\n// If no IPv6 addresses are found, an error is raised.\nfunc GetFirst6String(elems []string) (string, error) {\n\tips := []net.IP{}\n\tfor _, elem := range elems {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/util/net.go#L76-L112","documentation":"getFirst6 in pkg/util/net.go returns the first IPv6 address from a []net.IP (checked with netutils.IsIPv6), or 'no IPv6 address found' when none qualifies. It backs GetFirst6String and is used on dual-stack paths that must derive an IPv6 address (e.g. v6 node addresses or CIDRs for dual-stack networking).","triggerScenarios":"Dual-stack configuration paths calling getFirst6/GetFirst6String with a list containing only IPv4 addresses or unparsable strings (net.ParseIP returns nil for garbage, which is skipped) - e.g. --node-ip lacking a v6 entry on a dual-stack cluster, or an interface with no global v6 address.","commonSituations":"Enabling dual-stack without providing IPv6 addresses; v6 privacy extensions or link-local-only interfaces; flags copy-pasted from single-stack setups.","solutions":["Add an IPv6 to the relevant list: --node-ip=192.0.2.10,2001:db8::10 so a valid v6 exists.","Ensure the chosen interface has a global unicast IPv6 address (ip -6 addr show scope global).","If dual-stack is not intended, disable the dual-stack options so v6 derivation is not attempted.","Sanitize inputs: net.ParseIP each comma-separated entry and reject nils before passing them in."],"exampleFix":"# before: dual-stack enabled but no v6 supplied -> error\nk3s server --node-ip=192.0.2.10 --cluster-cidr=10.42.0.0/16,fd00:42::/56\n\n# after: node-ip includes the v6 address\nk3s server --node-ip=192.0.2.10,2001:db8::10 --cluster-cidr=10.42.0.0/16,fd00:42::/56","handlingStrategy":"validation","validationCode":"// Equivalent of GetFirst6String pre-check\ncount := 0\nfor _, s := range strings.Split(nodeIPFlag, \",\") {\n    if ip := net.ParseIP(s); ip != nil && netutils.IsIPv6(ip) {\n        count++\n    }\n}\nif count == 0 {\n    return errors.New(\"no IPv6 in node-ip list for dual-stack path\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"no IPv6 address found\") {\n    // supply a global unicast v6 via --node-ip or disable dual-stack\n}","preventionTips":["When enabling dual-stack, provide both v4 and v6 in --node-ip and CIDR flags.","Check 'ip -6 addr show scope global' on nodes before joining them dual-stack.","Prefer GetFirstString (family-agnostic with v6 fallback) where the family is not fixed."],"tags":["k3s","network","ipv6","node-ip","configuration","dual-stack"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}