k3s-io/k3s · error
no IPv6 address found
Error message
no IPv6 address found
What it means
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).
Source
Thrown at pkg/util/net.go:94
func JoinIP4Nets(elems []*net.IPNet) string {
var strs []string
for _, elem := range elems {
if elem != nil && elem.IP.To4() != nil {
strs = append(strs, elem.String())
}
}
return strings.Join(strs, ",")
}
// getFirst6 returns the first IPv6 address from the list of IP addresses.
// If no IPv6 addresses are found, an error is raised.
func getFirst6(elems []net.IP) (net.IP, error) {
for _, elem := range elems {
if elem != nil && netutils.IsIPv6(elem) {
return elem, nil
}
}
return nil, errors.New("no IPv6 address found")
}
// getFirst6Net returns the first IPv4 network from the list of IP networks.
// If no IPv6 addresses are found, an error is raised.
func getFirst6Net(elems []*net.IPNet) (*net.IPNet, error) {
for _, elem := range elems {
if elem != nil && netutils.IsIPv6(elem.IP) {
return elem, nil
}
}
return nil, errors.New("no IPv6 CIDRs found")
}
// GetFirst6String returns the first IPv6 address from a list of IP address strings.
// If no IPv6 addresses are found, an error is raised.
func GetFirst6String(elems []string) (string, error) {
ips := []net.IP{}
for _, elem := range elems {View on GitHub (pinned to 6ba341e396)
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.
Example fix
# before: dual-stack enabled but no v6 supplied -> error k3s server --node-ip=192.0.2.10 --cluster-cidr=10.42.0.0/16,fd00:42::/56 # after: node-ip includes the v6 address k3s server --node-ip=192.0.2.10,2001:db8::10 --cluster-cidr=10.42.0.0/16,fd00:42::/56
Defensive patterns
Strategy: validation
Validate before calling
// Equivalent of GetFirst6String pre-check
count := 0
for _, s := range strings.Split(nodeIPFlag, ",") {
if ip := net.ParseIP(s); ip != nil && netutils.IsIPv6(ip) {
count++
}
}
if count == 0 {
return errors.New("no IPv6 in node-ip list for dual-stack path")
} Try / catch
if err != nil && strings.Contains(err.Error(), "no IPv6 address found") {
// supply a global unicast v6 via --node-ip or disable dual-stack
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Enabling dual-stack without providing IPv6 addresses; v6 privacy extensions or link-local-only interfaces; flags copy-pasted from single-stack setups.
Related errors
- no IPv4 address found
- no IPv4 CIDRs found
- no IPv6 CIDRs found
- cluster-cidr: %v and service-cidr: %v, must share the same I
- invalid node-ip: %w
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/2ea81d45e3e44bba.
Report an issue: GitHub.