cilium/cilium · error
underlay protocol set to IPv6, but IPv6 is disabled
Error message
underlay protocol set to IPv6, but IPv6 is disabled
What it means
Mirror of the IPv4 case: with underlay-protocol=ipv6 but enable-ipv6=false, newConfig refuses the configuration because the selected underlay family is unavailable.
Source
Thrown at pkg/datapath/tunnel/tunnel.go:121
selectedUnderlay := UnderlayProtocol(in.Cfg.UnderlayProtocol)
switch selectedUnderlay {
case Auto:
switch {
case in.DaemonCfg.EnableIPv4:
selectedUnderlay = IPv4
case in.DaemonCfg.EnableIPv6:
selectedUnderlay = IPv6
default:
return configDisabled, fmt.Errorf("underlay protocol set to auto, but neither IPv4 nor IPv6 is enabled")
}
in.Logger.Info(fmt.Sprintf("Underlay protocol %s automatically selected", selectedUnderlay))
case IPv4:
if !in.DaemonCfg.EnableIPv4 {
return configDisabled, fmt.Errorf("underlay protocol set to IPv4, but IPv4 is disabled")
}
case IPv6:
if !in.DaemonCfg.EnableIPv6 {
return configDisabled, fmt.Errorf("underlay protocol set to IPv6, but IPv6 is disabled")
}
default:
return configDisabled, fmt.Errorf("invalid IP family for underlay %q", in.Cfg.UnderlayProtocol)
}
cfg := Config{
underlay: selectedUnderlay,
protocol: EncapProtocol(in.Cfg.TunnelProtocol),
port: in.Cfg.TunnelPort,
srcPortLow: 0,
srcPortHigh: 0,
deviceName: "",
shouldAdaptMTU: false,
}
if _, err := fmt.Sscanf(in.Cfg.TunnelSourcePortRange, "%d-%d", &cfg.srcPortLow, &cfg.srcPortHigh); err != nil {
return configDisabled, fmt.Errorf("invalid tunnel source port range %q", in.Cfg.TunnelSourcePortRange)
}View on GitHub (pinned to ac7b90affa)
Solutions
- Set tunnel-underlay-protocol=ipv4 (or auto) for IPv4-only clusters
- Or enable IPv6 (enable-ipv6=true / ipv6.enabled=true) if IPv6 underlay is intended
- Keep underlay-protocol=auto to let the agent pick the enabled family
Example fix
// before cilium-agent --tunnel-underlay-protocol=ipv6 --enable-ipv6=false // after cilium-agent --tunnel-underlay-protocol=ipv4
Defensive patterns
Strategy: validation
Validate before calling
if cfg.UnderlayProtocol == "ipv6" && !cfg.EnableIPv6 {
return errors.New("tunnel-underlay-protocol=ipv6 requires enable-ipv6=true")
} Type guard
func underlayMatchesFamily(underlay string, v4, v6 bool) bool {
switch underlay {
case "auto": return v4 || v6
case "ipv4": return v4
case "ipv6": return v6
}
return false
} Try / catch
if err := agent.Start(); err != nil {
if strings.Contains(err.Error(), "underlay protocol set to IPv6") {
log.Fatal("enable IPv6 or use ipv4/auto underlay")
}
} Prevention
- Use underlay-protocol=auto on IPv4-only clusters
- Enable IPv6 explicitly if IPv6 underlay is intended
- Keep the underlay family within the enabled node families
When it happens
Trigger: tunnel-underlay-protocol=ipv6 on a cluster where IPv6 is not enabled (enable-ipv6=false) — most IPv4-only clusters.
Common situations: Operators experimenting with IPv6 underlay on an IPv4-only cluster, Helm chart with tunnelUnderlayProtocol=ipv6 but ipv6.enabled left false.
Related errors
- underlay protocol set to auto, but neither IPv4 nor IPv6 is
- not ready
- no cilium agent pods found
- egress gateway requires an IPv4 underlay
- failed to allocate service loopback IPs: %w
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/e2caea19350247a5.
Report an issue: GitHub.