k3s-io/k3s · error
ip: %v is not ipv4 or ipv6
Error message
ip: %v is not ipv4 or ipv6
What it means
GetDefaultAddresses picks cluster defaults based on the family of the node IP: for IPv4 it returns 0.0.0.0 with 10.42.0.0/16 and 10.43.0.0/16; for IPv6 '::' with fd00:42::/56 and fd00:43::/112. If netutils.IsIPv4 and netutils.IsIPv6 are both false - in practice a nil or zero-length net.IP - it refuses to choose defaults.
Source
Thrown at pkg/util/net.go:216
if ip := net.ParseIP(v); ip != nil {
return v
}
}
}
return ""
}
// GetFirstIP checks what is the IPFamily of the first item. Based on that, returns a set of values
func GetDefaultAddresses(nodeIP net.IP) (string, string, string, error) {
if netutils.IsIPv4(nodeIP) {
return "0.0.0.0", "10.42.0.0/16", "10.43.0.0/16", nil
}
if netutils.IsIPv6(nodeIP) {
return "::", "fd00:42::/56", "fd00:43::/112", nil
}
return "", "", "", fmt.Errorf("ip: %v is not ipv4 or ipv6", nodeIP)
}
// GetFirstString returns the first IP4 address from a list of IP address strings.
// If no IPv4 addresses are found, returns the first IPv6 address
// if neither of IPv4 or IPv6 are found an error is raised.
func GetFirstString(elems []string) (string, bool, error) {
ip, err := GetFirst4String(elems)
v6only := false
if err != nil {
ip, err = GetFirst6String(elems)
if err != nil {
return "", false, err
}
v6only = true
}
return ip, v6only, nil
}
View on GitHub (pinned to 6ba341e396)
Solutions
- Log or assert the input IP right before the call; nil/empty means fix the upstream parse
- Ensure the node-ip config is valid so a non-nil IP reaches this function
- If the value came from net.ParseIP, check err/ip==nil at that call site first
Example fix
// before
defBind, podCIDR, svcCIDR, err := util.GetDefaultAddresses(ip) // ip may be nil
// after
if ip == nil {
return fmt.Errorf("node IP is empty")
}
defBind, podCIDR, svcCIDR, err := util.GetDefaultAddresses(ip) Defensive patterns
Strategy: type-guard
Validate before calling
if ip == nil || !(netutils.IsIPv4(ip) || netutils.IsIPv6(ip)) {
return fmt.Errorf("node IP %v has no usable family", ip)
} Type guard
func usableNodeIP(ip net.IP) bool {
return ip != nil && len(ip) > 0 && (netutils.IsIPv4(ip) || netutils.IsIPv6(ip))
} Try / catch
bind, podCIDR, svcCIDR, err := util.GetDefaultAddresses(ip)
if err != nil {
if strings.Contains(err.Error(), "is not ipv4 or ipv6") {
// nil/garbage IP reached us: fix the upstream parse instead of choosing defaults
return fmt.Errorf("node IP unset or unparsable: %v", ip)
}
return "", "", "", err
} Prevention
- Always check the nil return of net.ParseIP before using the result
- Guard call sites that derive defaults from an IP with an IsIPv4/IsIPv6 check
- Log the effective node IP at startup to catch empty values early
When it happens
Trigger: Calling GetDefaultAddresses with a nil net.IP, typically a net.ParseIP failure whose nil result was not checked upstream, or an unset node-ip that reached this call as nil.
Common situations: Code paths where node-ip parsing failed silently upstream; dual-stack edge cases where the IP variable was never assigned; passing net.ParseIP(s) directly without checking the nil return.
Related errors
- invalid node-ip: %w
- invalid ip format '%s'
- no IPv4 CIDRs found
- no IPv4 address found
- no IPv6 address found
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/2edf43818bd321d8.
Report an issue: GitHub.