k3s-io/k3s · error

VPN Error. The passed VPN auth info includes an unknown para

Error message

VPN Error. The passed VPN auth info includes an unknown parameter: %v

What it means

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.

Source

Thrown at pkg/vpn/vpn.go:132

func getVPNAuthInfo(vpnAuth string) (vpnCliAuthInfo, error) {
	var authInfo vpnCliAuthInfo

	// Separate extraArgs which will be passed directly to the vpn binary command
	vpnCommand, extraArgs := processCLIArgs(vpnAuth)
	authInfo.ExtraCLIFlags = extraArgs

	vpnParameters := strings.Split(vpnCommand, ",")
	for _, vpnKeyValues := range vpnParameters {
		vpnKeyValue := strings.Split(vpnKeyValues, "=")
		switch vpnKeyValue[0] {
		case "name":
			authInfo.Name = vpnKeyValue[1]
		case "joinKey":
			authInfo.JoinKey = vpnKeyValue[1]
		case "controlServerURL":
			authInfo.ControlServerURL = vpnKeyValue[1]
		default:
			return vpnCliAuthInfo{}, fmt.Errorf("VPN Error. The passed VPN auth info includes an unknown parameter: %v", vpnKeyValue[0])
		}
	}

	if err := isVPNConfigOK(authInfo); err != nil {
		return authInfo, err
	}
	return authInfo, nil
}

// isVPNConfigOK checks that the config is complete
func isVPNConfigOK(authInfo vpnCliAuthInfo) error {
	if authInfo.Name == "tailscale" {
		if authInfo.JoinKey == "" {
			return errors.New("VPN Error. Tailscale requires a JoinKey")
		}
		if authInfo.ControlServerURL != "" {
			if _, err := url.Parse(authInfo.ControlServerURL); err != nil {
				return fmt.Errorf("VPN Error. Invalid control server URL for Tailscale: %w", err)

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Use exactly the three lowercase keys in key=value form: name, joinKey, controlServerURL
  2. Rename common mistakes: authkey to joinKey, server/login-server to controlServerURL
  3. Remove trailing commas, empty segments, and commas inside values

Example fix

# before
name=tailscale,authkey=tskey-xxxx
# after
name=tailscale,joinKey=tskey-xxxx
Defensive patterns

Strategy: validation

Validate before calling

var vpnKeys = map[string]bool{"name": true, "joinKey": true, "controlServerURL": true}

func validateVPNAuth(vpnAuth string) error {
	for _, seg := range strings.Split(vpnAuth, ",") {
		parts := strings.SplitN(seg, "=", 2)
		if len(parts) != 2 || !vpnKeys[parts[0]] {
			return fmt.Errorf("bad VPN auth segment %q (allowed keys: name, joinKey, controlServerURL)", seg)
		}
	}
	return nil
}

Type guard

func isKnownVPNKey(k string) bool {
	switch k {
	case "name", "joinKey", "controlServerURL":
		return true
	}
	return false
}

Try / catch

_, err := vpn.GetInfo(vpnAuth)
if err != nil {
	if strings.Contains(err.Error(), "unknown parameter") {
		// the offending key is named in the message; correct it (commonly authkey -> joinKey)
	}
	return nil, err
}

Prevention

When it happens

Trigger: Passing 'name=tailscale,authkey=tskey-...' (the recognized key is joinKey, not authkey); a segment with no '=' at all; case mismatches like 'Name=' or 'JoinKey='.

Common situations: 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.

Related errors


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