k3s-io/k3s · error

Requested VPN: %s is not supported. We currently only suppor

Error message

Requested VPN: %s is not supported. We currently only support tailscale

What it means

StartVPN dispatches on the name parsed from the VPN auth config; only "tailscale" is implemented, so any other name (wireguard, openvpn, a typo, or an unset name that defaulted to something else) reaches the default branch. The integration surface (InfoProvider, vpnCliAuthInfo) is deliberately general, but there is currently a single backend.

Source

Thrown at pkg/vpn/vpn.go:88

		}
		if authInfo.ControlServerURL != "" {
			args = append(args, "--login-server", authInfo.ControlServerURL)
		}
		if len(authInfo.ExtraCLIFlags) > 0 {
			args = append(args, authInfo.ExtraCLIFlags...)
		}
		logrus.Debugf("Flags passed to tailscale up: %v", args)
		output, err := util.ExecCommand("tailscale", args)
		if err != nil {
			if output != "" {
				return errors.WithMessagef(err, "tailscale up failed (%q)", output)
			}
			return errors.WithMessage(err, "tailscale up failed")
		}
		logrus.Debugf("Output from tailscale up: %v", output)
		return nil
	default:
		return fmt.Errorf("Requested VPN: %s is not supported. We currently only support tailscale", authInfo.Name)
	}
}

// GetInfo returns an Info object with details about the VPN. General function in case we want to add more vpn integrations
func GetInfo(vpnAuth string) (*Info, error) {
	authInfo, err := getVPNAuthInfo(vpnAuth)
	if err != nil {
		return nil, err
	}

	if authInfo.Name == "tailscale" {
		return getTailscaleInfo()
	}
	return nil, nil
}

func GetInfoFromExecutor() (*Info, error) {
	ex := executor.Get()

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Set the auth config to name=tailscale (plus joinKey=tskey-...)
  2. Verify the auth string is comma-separated key=value with only the recognized keys
  3. If you need another VPN backend, it must be implemented in pkg/vpn - it is not configurable today

Example fix

# before
name=wireguard,joinKey=xxxxx
# after
name=tailscale,joinKey=tskey-auth-xxxxx
Defensive patterns

Strategy: validation

Validate before calling

func supportsVPN(vpnAuth string) bool {
	for _, kv := range strings.Split(vpnAuth, ",") {
		if strings.HasPrefix(kv, "name=") {
			return strings.TrimPrefix(kv, "name=") == "tailscale"
		}
	}
	return false
}

if !supportsVPN(vpnAuth) {
	return fmt.Errorf("only name=tailscale is supported")
}

Try / catch

if err := vpn.StartVPN(vpnAuthFile); err != nil {
	if strings.Contains(err.Error(), "is not supported. We currently only support tailscale") {
		// fix the name= value in the auth config; do not retry as-is
	}
	return err
}

Prevention

When it happens

Trigger: StartVPN or GetInfo with a vpnAuth string/file whose name key is anything other than exactly 'tailscale'.

Common situations: Users assuming other VPN providers are supported; typos like 'tailscales'; an auth config borrowed from another tool's format so the name field parses to an unexpected value.

Related errors


AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15). Data as JSON: /api/errors/6d730b04706993b5. Report an issue: GitHub.