{"record":{"id":"5abc087be31d440f","repo":"k3s-io/k3s","slug":"vpn-error-the-passed-vpn-auth-info-includes-an-un","errorCode":null,"errorMessage":"VPN Error. The passed VPN auth info includes an unknown parameter: %v","messagePattern":"VPN Error\\. The passed VPN auth info includes an unknown parameter: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/vpn/vpn.go","lineNumber":132,"sourceCode":"func getVPNAuthInfo(vpnAuth string) (vpnCliAuthInfo, error) {\n\tvar authInfo vpnCliAuthInfo\n\n\t// Separate extraArgs which will be passed directly to the vpn binary command\n\tvpnCommand, extraArgs := processCLIArgs(vpnAuth)\n\tauthInfo.ExtraCLIFlags = extraArgs\n\n\tvpnParameters := strings.Split(vpnCommand, \",\")\n\tfor _, vpnKeyValues := range vpnParameters {\n\t\tvpnKeyValue := strings.Split(vpnKeyValues, \"=\")\n\t\tswitch vpnKeyValue[0] {\n\t\tcase \"name\":\n\t\t\tauthInfo.Name = vpnKeyValue[1]\n\t\tcase \"joinKey\":\n\t\t\tauthInfo.JoinKey = vpnKeyValue[1]\n\t\tcase \"controlServerURL\":\n\t\t\tauthInfo.ControlServerURL = vpnKeyValue[1]\n\t\tdefault:\n\t\t\treturn vpnCliAuthInfo{}, fmt.Errorf(\"VPN Error. The passed VPN auth info includes an unknown parameter: %v\", vpnKeyValue[0])\n\t\t}\n\t}\n\n\tif err := isVPNConfigOK(authInfo); err != nil {\n\t\treturn authInfo, err\n\t}\n\treturn authInfo, nil\n}\n\n// isVPNConfigOK checks that the config is complete\nfunc isVPNConfigOK(authInfo vpnCliAuthInfo) error {\n\tif authInfo.Name == \"tailscale\" {\n\t\tif authInfo.JoinKey == \"\" {\n\t\t\treturn errors.New(\"VPN Error. Tailscale requires a JoinKey\")\n\t\t}\n\t\tif authInfo.ControlServerURL != \"\" {\n\t\t\tif _, err := url.Parse(authInfo.ControlServerURL); err != nil {\n\t\t\t\treturn fmt.Errorf(\"VPN Error. Invalid control server URL for Tailscale: %w\", err)","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/vpn/vpn.go#L114-L150","documentation":"getVPNAuthInfo splits the vpnAuth string on commas, then each item on '='; the key (element 0) must be one of name, joinKey, controlServerURL. Anything else - an unknown key or a bare token without '=' - is rejected here. Note the keys are case-sensitive, and a known key written without '=' would index-panic on vpnKeyValue[1], so always use key=value form.","triggerScenarios":"Passing 'name=tailscale,authkey=tskey-...' (the recognized key is joinKey, not authkey); a segment with no '=' at all; case mismatches like 'Name=' or 'JoinKey='.","commonSituations":"Users copying tailscale CLI flag names (--authkey) into the string; stray separators or trailing commas; values containing commas which split the segment and produce garbage keys.","solutions":["Use exactly the three lowercase keys in key=value form: name, joinKey, controlServerURL","Rename common mistakes: authkey to joinKey, server/login-server to controlServerURL","Remove trailing commas, empty segments, and commas inside values"],"exampleFix":"# before\nname=tailscale,authkey=tskey-xxxx\n# after\nname=tailscale,joinKey=tskey-xxxx","handlingStrategy":"validation","validationCode":"var vpnKeys = map[string]bool{\"name\": true, \"joinKey\": true, \"controlServerURL\": true}\n\nfunc validateVPNAuth(vpnAuth string) error {\n\tfor _, seg := range strings.Split(vpnAuth, \",\") {\n\t\tparts := strings.SplitN(seg, \"=\", 2)\n\t\tif len(parts) != 2 || !vpnKeys[parts[0]] {\n\t\t\treturn fmt.Errorf(\"bad VPN auth segment %q (allowed keys: name, joinKey, controlServerURL)\", seg)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func isKnownVPNKey(k string) bool {\n\tswitch k {\n\tcase \"name\", \"joinKey\", \"controlServerURL\":\n\t\treturn true\n\t}\n\treturn false\n}","tryCatchPattern":"_, err := vpn.GetInfo(vpnAuth)\nif err != nil {\n\tif strings.Contains(err.Error(), \"unknown parameter\") {\n\t\t// the offending key is named in the message; correct it (commonly authkey -> joinKey)\n\t}\n\treturn nil, err\n}","preventionTips":["Only pass the three recognized keys: name, joinKey, controlServerURL (case-sensitive)","Always write segments as key=value - a missing '=' can panic the parser on known keys","Do not embed commas in values; they split the segment and corrupt parsing","Map tailscale CLI flags to config keys: --authkey is joinKey, --login-server is controlServerURL"],"tags":["go","vpn","configuration","parsing","tailscale"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}