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

  1. Set tunnel-underlay-protocol=ipv4 (or auto) for IPv4-only clusters
  2. Or enable IPv6 (enable-ipv6=true / ipv6.enabled=true) if IPv6 underlay is intended
  3. 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

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


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/e2caea19350247a5. Report an issue: GitHub.