{"record":{"id":"e2caea19350247a5","repo":"cilium/cilium","slug":"underlay-protocol-set-to-ipv6-but-ipv6-is-disable","errorCode":null,"errorMessage":"underlay protocol set to IPv6, but IPv6 is disabled","messagePattern":"underlay protocol set to IPv6, but IPv6 is disabled","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/datapath/tunnel/tunnel.go","lineNumber":121,"sourceCode":"\tselectedUnderlay := UnderlayProtocol(in.Cfg.UnderlayProtocol)\n\tswitch selectedUnderlay {\n\tcase Auto:\n\t\tswitch {\n\t\tcase in.DaemonCfg.EnableIPv4:\n\t\t\tselectedUnderlay = IPv4\n\t\tcase in.DaemonCfg.EnableIPv6:\n\t\t\tselectedUnderlay = IPv6\n\t\tdefault:\n\t\t\treturn configDisabled, fmt.Errorf(\"underlay protocol set to auto, but neither IPv4 nor IPv6 is enabled\")\n\t\t}\n\t\tin.Logger.Info(fmt.Sprintf(\"Underlay protocol %s automatically selected\", selectedUnderlay))\n\tcase IPv4:\n\t\tif !in.DaemonCfg.EnableIPv4 {\n\t\t\treturn configDisabled, fmt.Errorf(\"underlay protocol set to IPv4, but IPv4 is disabled\")\n\t\t}\n\tcase IPv6:\n\t\tif !in.DaemonCfg.EnableIPv6 {\n\t\t\treturn configDisabled, fmt.Errorf(\"underlay protocol set to IPv6, but IPv6 is disabled\")\n\t\t}\n\tdefault:\n\t\treturn configDisabled, fmt.Errorf(\"invalid IP family for underlay %q\", in.Cfg.UnderlayProtocol)\n\t}\n\n\tcfg := Config{\n\t\tunderlay:       selectedUnderlay,\n\t\tprotocol:       EncapProtocol(in.Cfg.TunnelProtocol),\n\t\tport:           in.Cfg.TunnelPort,\n\t\tsrcPortLow:     0,\n\t\tsrcPortHigh:    0,\n\t\tdeviceName:     \"\",\n\t\tshouldAdaptMTU: false,\n\t}\n\n\tif _, err := fmt.Sscanf(in.Cfg.TunnelSourcePortRange, \"%d-%d\", &cfg.srcPortLow, &cfg.srcPortHigh); err != nil {\n\t\treturn configDisabled, fmt.Errorf(\"invalid tunnel source port range %q\", in.Cfg.TunnelSourcePortRange)\n\t}","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/datapath/tunnel/tunnel.go#L103-L139","documentation":"Mirror of the IPv4 case: with underlay-protocol=ipv6 but enable-ipv6=false, newConfig refuses the configuration because the selected underlay family is unavailable.","triggerScenarios":"tunnel-underlay-protocol=ipv6 on a cluster where IPv6 is not enabled (enable-ipv6=false) — most IPv4-only clusters.","commonSituations":"Operators experimenting with IPv6 underlay on an IPv4-only cluster, Helm chart with tunnelUnderlayProtocol=ipv6 but ipv6.enabled left false.","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"],"exampleFix":"// before\ncilium-agent --tunnel-underlay-protocol=ipv6 --enable-ipv6=false\n// after\ncilium-agent --tunnel-underlay-protocol=ipv4","handlingStrategy":"validation","validationCode":"if cfg.UnderlayProtocol == \"ipv6\" && !cfg.EnableIPv6 {\n    return errors.New(\"tunnel-underlay-protocol=ipv6 requires enable-ipv6=true\")\n}","typeGuard":"func underlayMatchesFamily(underlay string, v4, v6 bool) bool {\n    switch underlay {\n    case \"auto\": return v4 || v6\n    case \"ipv4\": return v4\n    case \"ipv6\": return v6\n    }\n    return false\n}","tryCatchPattern":"if err := agent.Start(); err != nil {\n    if strings.Contains(err.Error(), \"underlay protocol set to IPv6\") {\n        log.Fatal(\"enable IPv6 or use ipv4/auto underlay\")\n    }\n}","preventionTips":["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"],"tags":["cilium","configuration","tunnel","ipv6"],"backgroundTag":"invalid-tunnel-protocol","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}