{"record":{"id":"6d730b04706993b5","repo":"k3s-io/k3s","slug":"requested-vpn-s-is-not-supported-we-currently-o","errorCode":null,"errorMessage":"Requested VPN: %s is not supported. We currently only support tailscale","messagePattern":"Requested VPN: (.+?) is not supported\\. We currently only support tailscale","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/vpn/vpn.go","lineNumber":88,"sourceCode":"\t\t}\n\t\tif authInfo.ControlServerURL != \"\" {\n\t\t\targs = append(args, \"--login-server\", authInfo.ControlServerURL)\n\t\t}\n\t\tif len(authInfo.ExtraCLIFlags) > 0 {\n\t\t\targs = append(args, authInfo.ExtraCLIFlags...)\n\t\t}\n\t\tlogrus.Debugf(\"Flags passed to tailscale up: %v\", args)\n\t\toutput, err := util.ExecCommand(\"tailscale\", args)\n\t\tif err != nil {\n\t\t\tif output != \"\" {\n\t\t\t\treturn errors.WithMessagef(err, \"tailscale up failed (%q)\", output)\n\t\t\t}\n\t\t\treturn errors.WithMessage(err, \"tailscale up failed\")\n\t\t}\n\t\tlogrus.Debugf(\"Output from tailscale up: %v\", output)\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"Requested VPN: %s is not supported. We currently only support tailscale\", authInfo.Name)\n\t}\n}\n\n// GetInfo returns an Info object with details about the VPN. General function in case we want to add more vpn integrations\nfunc GetInfo(vpnAuth string) (*Info, error) {\n\tauthInfo, err := getVPNAuthInfo(vpnAuth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif authInfo.Name == \"tailscale\" {\n\t\treturn getTailscaleInfo()\n\t}\n\treturn nil, nil\n}\n\nfunc GetInfoFromExecutor() (*Info, error) {\n\tex := executor.Get()","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/vpn/vpn.go#L70-L106","documentation":"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.","triggerScenarios":"StartVPN or GetInfo with a vpnAuth string/file whose name key is anything other than exactly 'tailscale'.","commonSituations":"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.","solutions":["Set the auth config to name=tailscale (plus joinKey=tskey-...)","Verify the auth string is comma-separated key=value with only the recognized keys","If you need another VPN backend, it must be implemented in pkg/vpn - it is not configurable today"],"exampleFix":"# before\nname=wireguard,joinKey=xxxxx\n# after\nname=tailscale,joinKey=tskey-auth-xxxxx","handlingStrategy":"validation","validationCode":"func supportsVPN(vpnAuth string) bool {\n\tfor _, kv := range strings.Split(vpnAuth, \",\") {\n\t\tif strings.HasPrefix(kv, \"name=\") {\n\t\t\treturn strings.TrimPrefix(kv, \"name=\") == \"tailscale\"\n\t\t}\n\t}\n\treturn false\n}\n\nif !supportsVPN(vpnAuth) {\n\treturn fmt.Errorf(\"only name=tailscale is supported\")\n}","typeGuard":null,"tryCatchPattern":"if err := vpn.StartVPN(vpnAuthFile); err != nil {\n\tif strings.Contains(err.Error(), \"is not supported. We currently only support tailscale\") {\n\t\t// fix the name= value in the auth config; do not retry as-is\n\t}\n\treturn err\n}","preventionTips":["Use exactly name=tailscale in the VPN auth string","Keep a schema check on the auth string at config load time","Track upstream releases if you need other VPN backends - the code is single-backend today"],"tags":["go","vpn","tailscale","configuration"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}