{"record":{"id":"96cdbcabf4bb7d4e","repo":"k3s-io/k3s","slug":"tailscale-does-not-provide-an-ipv4-address","errorCode":null,"errorMessage":"tailscale does not provide an ipv4 address","messagePattern":"tailscale does not provide an ipv4 address","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cli/server/server.go","lineNumber":539,"sourceCode":"\t\t\tif vpnInfo.IPv6Address != nil {\n\t\t\t\tlogrus.Infof(\"Changed advertise-address to %v due to VPN\", vpnInfo.IPv6Address)\n\t\t\t\tif serverConfig.ControlConfig.AdvertiseIP != \"\" {\n\t\t\t\t\tlogrus.Warn(\"Conflict in the config detected. VPN integration overwrites advertise-address but the config is setting the advertise-address parameter\")\n\t\t\t\t}\n\t\t\t\tserverConfig.ControlConfig.AdvertiseIP = vpnInfo.IPv6Address.String()\n\t\t\t} else {\n\t\t\t\treturn errors.New(\"tailscale does not provide an ipv6 address\")\n\t\t\t}\n\t\t} else {\n\t\t\t// We are in dual-stack or ipv4-only mode\n\t\t\tif vpnInfo.IPv4Address != nil {\n\t\t\t\tlogrus.Infof(\"Changed advertise-address to %v due to VPN\", vpnInfo.IPv4Address)\n\t\t\t\tif serverConfig.ControlConfig.AdvertiseIP != \"\" {\n\t\t\t\t\tlogrus.Warn(\"Conflict in the config detected. VPN integration overwrites advertise-address but the config is setting the advertise-address parameter\")\n\t\t\t\t}\n\t\t\t\tserverConfig.ControlConfig.AdvertiseIP = vpnInfo.IPv4Address.String()\n\t\t\t} else {\n\t\t\t\treturn errors.New(\"tailscale does not provide an ipv4 address\")\n\t\t\t}\n\t\t}\n\t\tlogrus.Warn(\"Etcd IP (PrivateIP) remains the local IP. Running etcd traffic over VPN is not recommended due to performance issues\")\n\t} else {\n\t\t// if not set, try setting advertise-ip from agent node-external-ip\n\t\tif serverConfig.ControlConfig.AdvertiseIP == \"\" && len(cmds.AgentConfig.NodeExternalIP.Value()) != 0 {\n\t\t\tserverConfig.ControlConfig.AdvertiseIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeExternalIP.Value())\n\t\t}\n\n\t\t// if not set, try setting advertise-ip from agent node-ip\n\t\tif serverConfig.ControlConfig.AdvertiseIP == \"\" && len(cmds.AgentConfig.NodeIP.Value()) != 0 {\n\t\t\tserverConfig.ControlConfig.AdvertiseIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeIP.Value())\n\t\t}\n\t}\n\n\t// if we ended up with any advertise-ips, ensure they're added to the SAN list\n\t// before PrepareServer generates the apiserver serving certificate;\n\t// note that kube-apiserver does not support dual-stack advertise-ip as of 1.21.0:","sourceCodeStart":521,"sourceCodeEnd":557,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/cli/server/server.go#L521-L557","documentation":"The mirror of the IPv6 case: when the node runs dual-stack or IPv4-only and the tailscale/VPN integration is active, k3s overwrites the advertise address with the VPN's IPv4 address. If the VPN reports no IPv4 address, startup fails instead of advertising an unreachable address.","triggerScenarios":"Node with IPv4/dual-stack node-ip started with --vpn-config/--vpn-auth where vpnInfo.IPv4Address is nil — e.g. an IPv6-only tailnet or tailscale returning only v6 addresses.","commonSituations":"IPv6-only tailnets where tailscale has no A record for the node; VPN executor returning incomplete info; mixing IPv6-only tailscale deployment with IPv4 k3s nodes.","solutions":["Make the tailnet provide the node an IPv4 address (or fix the tailscale config) and retry","Move the node to IPv6-only node-ip so the IPv6 branch applies","Drop --vpn-config/--vpn-auth and configure --advertise-address manually"],"exampleFix":"# before\nk3s server --node-ip=10.0.0.10 --vpn-config=hostname=tsw1   # tailnet is v6-only\n\n# after\nk3s server --node-ip=fd00::10 --vpn-config=hostname=tsw1","handlingStrategy":"validation","validationCode":"// before enabling vpn integration on ipv4/dual-stack nodes\ninfo, _ := vpn.GetInfoFromExecutor()\nif info != nil && info.IPv4Address == nil && !utilsnet.IsIPv6(net.ParseIP(cmds.AgentConfig.NodeIP.Value()[0])) {\n    return errors.New(\"VPN has no IPv4 address; fix tailscale or drop --vpn-* flags\")\n}","typeGuard":"func vpnHasIPv4(vpnInfo *vpn.Info) bool { return vpnInfo != nil && vpnInfo.IPv4Address != nil }","tryCatchPattern":null,"preventionTips":["Verify with `tailscale ip -4` that the node has a v4 address before using VPN advertise-address","Keep node IP family consistent with tailnet addressing","Treat vpn-info hooks as external input: validate both address fields"],"tags":["tailscale","vpn","ipv4","networking"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}