k3s-io/k3s · error
tailscale does not provide an ipv4 address
Error message
tailscale does not provide an ipv4 address
What it means
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.
Source
Thrown at pkg/cli/server/server.go:539
if vpnInfo.IPv6Address != nil {
logrus.Infof("Changed advertise-address to %v due to VPN", vpnInfo.IPv6Address)
if serverConfig.ControlConfig.AdvertiseIP != "" {
logrus.Warn("Conflict in the config detected. VPN integration overwrites advertise-address but the config is setting the advertise-address parameter")
}
serverConfig.ControlConfig.AdvertiseIP = vpnInfo.IPv6Address.String()
} else {
return errors.New("tailscale does not provide an ipv6 address")
}
} else {
// We are in dual-stack or ipv4-only mode
if vpnInfo.IPv4Address != nil {
logrus.Infof("Changed advertise-address to %v due to VPN", vpnInfo.IPv4Address)
if serverConfig.ControlConfig.AdvertiseIP != "" {
logrus.Warn("Conflict in the config detected. VPN integration overwrites advertise-address but the config is setting the advertise-address parameter")
}
serverConfig.ControlConfig.AdvertiseIP = vpnInfo.IPv4Address.String()
} else {
return errors.New("tailscale does not provide an ipv4 address")
}
}
logrus.Warn("Etcd IP (PrivateIP) remains the local IP. Running etcd traffic over VPN is not recommended due to performance issues")
} else {
// if not set, try setting advertise-ip from agent node-external-ip
if serverConfig.ControlConfig.AdvertiseIP == "" && len(cmds.AgentConfig.NodeExternalIP.Value()) != 0 {
serverConfig.ControlConfig.AdvertiseIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeExternalIP.Value())
}
// if not set, try setting advertise-ip from agent node-ip
if serverConfig.ControlConfig.AdvertiseIP == "" && len(cmds.AgentConfig.NodeIP.Value()) != 0 {
serverConfig.ControlConfig.AdvertiseIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeIP.Value())
}
}
// if we ended up with any advertise-ips, ensure they're added to the SAN list
// before PrepareServer generates the apiserver serving certificate;
// note that kube-apiserver does not support dual-stack advertise-ip as of 1.21.0:View on GitHub (pinned to 6ba341e396)
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
Example fix
# before k3s server --node-ip=10.0.0.10 --vpn-config=hostname=tsw1 # tailnet is v6-only # after k3s server --node-ip=fd00::10 --vpn-config=hostname=tsw1
Defensive patterns
Strategy: validation
Validate before calling
// before enabling vpn integration on ipv4/dual-stack nodes
info, _ := vpn.GetInfoFromExecutor()
if info != nil && info.IPv4Address == nil && !utilsnet.IsIPv6(net.ParseIP(cmds.AgentConfig.NodeIP.Value()[0])) {
return errors.New("VPN has no IPv4 address; fix tailscale or drop --vpn-* flags")
} Type guard
func vpnHasIPv4(vpnInfo *vpn.Info) bool { return vpnInfo != nil && vpnInfo.IPv4Address != nil } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- incorrect netMode for flannel tailscale backend
- tailscale does not provide an ipv6 address
- ipv4 mode requested but no ipv4 network provided
- VPN Error. Tailscale requires a JoinKey
- Requested VPN: %s is not supported. We currently only suppor
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/96cdbcabf4bb7d4e.
Report an issue: GitHub.