k3s-io/k3s · error
invalid token format
Error message
invalid token format
What it means
After the optional CA hash is split off, the credential segment must parse either as a kubeadm bootstrap token string (<6-char id>.<16-char secret>) or as basic auth (<username>:<password> with a non-empty password). If neither shape matches, parseToken rejects the input as an invalid token format.
Source
Thrown at pkg/clientaccess/token.go:251
// Split into CA hash and creds.
parts := strings.SplitN(token, "::", 2)
token = parts[0]
if len(parts) > 1 {
hashLen := len(parts[0])
if hashLen > 0 && hashLen != caHashLength {
return nil, errors.New("invalid token CA hash length")
}
info.caHash = parts[0]
token = parts[1]
}
// Try to parse creds as bootstrap token string; fall back to basic auth.
// If neither works, error.
bts, err := kubeadm.NewBootstrapTokenString(token)
if err != nil {
parts = strings.SplitN(token, ":", 2)
if len(parts) != 2 || len(parts[1]) == 0 {
return nil, errors.New("invalid token format")
}
info.Username = parts[0]
info.Password = parts[1]
} else {
info.BootstrapTokenString = bts
}
return &info, nil
}
// GetHTTPClient returns a http client that validates TLS server certificates using the provided CA bundle.
// If the CA bundle is empty, it validates using the default http client using the OS CA bundle.
// If the CA bundle is not empty but does not contain any valid certs, it validates using
// an empty CA bundle (which will always fail).
// If valid cert+key paths can be loaded from the provided paths, they are used for client cert auth.
func GetHTTPClient(cacerts []byte, certFile, keyFile string, options ...any) *http.Client {
if len(cacerts) == 0 {
return defaultClientView on GitHub (pinned to 6ba341e396)
Solutions
- Regenerate the token on the seed server with `k3s token create` and use the exact output
- Validate shape before use: creds must match ^[a-z0-9]{6}\.[a-z0-9]{16}$ or ^[^:]+:.+$
- Never assemble tokens by string concatenation from parts
Example fix
# before (empty password / malformed creds) K10::<hash>::admin: # after K10::<hash>::abcdef.0123456789abcdef
Defensive patterns
Strategy: validation
Validate before calling
creds := tokenAfterHashSegment // part after '::'
bootstrap := regexp.MustCompile(`^[a-z0-9]{6}\.[a-z0-9]{16}$`)
basic := regexp.MustCompile(`^[^:\s]+:.+$`)
if !bootstrap.MatchString(creds) && !basic.MatchString(creds) {
return fmt.Errorf("invalid token format: %q", creds)
} Type guard
func isK3sCredsSegment(creds string) bool {
bootstrap := regexp.MustCompile(`^[a-z0-9]{6}\.[a-z0-9]{16}$`)
basic := regexp.MustCompile(`^[^:\s]+:.+$`)
return bootstrap.MatchString(creds) || basic.MatchString(creds)
} Try / catch
if err != nil && strings.Contains(err.Error(), "invalid token format") {
return fmt.Errorf("join token malformed; regenerate with `k3s token create` on the seed server")
} Prevention
- Never hand-assemble tokens from parts
- Regenerate rather than repair suspect tokens
- Keep token-producing automation (k3s token create) as the single source
When it happens
Trigger: Tokens like `K10::<user>:` (empty password after the colon), `K10::justarandomstring`, or credentials where the '::' vs ':' separators got collapsed/reordered during transcription.
Common situations: Hand-editing tokens; scripts that join server URL and token with the wrong separator; credentials rotated into a secret with a missing field; pasting only the ID portion of a bootstrap token.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- invalid token CA hash length
- token must not be empty
- only https:// URLs are supported, invalid scheme:
- invalid output format: {cfg.Output}
- Failed checking netMode
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/f3c42b75b27fbb11.
Report an issue: GitHub.