{"record":{"id":"f3c42b75b27fbb11","repo":"k3s-io/k3s","slug":"invalid-token-format","errorCode":null,"errorMessage":"invalid token format","messagePattern":"invalid token format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/clientaccess/token.go","lineNumber":251,"sourceCode":"\t// Split into CA hash and creds.\n\tparts := strings.SplitN(token, \"::\", 2)\n\ttoken = parts[0]\n\tif len(parts) > 1 {\n\t\thashLen := len(parts[0])\n\t\tif hashLen > 0 && hashLen != caHashLength {\n\t\t\treturn nil, errors.New(\"invalid token CA hash length\")\n\t\t}\n\t\tinfo.caHash = parts[0]\n\t\ttoken = parts[1]\n\t}\n\n\t// Try to parse creds as bootstrap token string; fall back to basic auth.\n\t// If neither works, error.\n\tbts, err := kubeadm.NewBootstrapTokenString(token)\n\tif err != nil {\n\t\tparts = strings.SplitN(token, \":\", 2)\n\t\tif len(parts) != 2 || len(parts[1]) == 0 {\n\t\t\treturn nil, errors.New(\"invalid token format\")\n\t\t}\n\t\tinfo.Username = parts[0]\n\t\tinfo.Password = parts[1]\n\t} else {\n\t\tinfo.BootstrapTokenString = bts\n\t}\n\n\treturn &info, nil\n}\n\n// GetHTTPClient returns a http client that validates TLS server certificates using the provided CA bundle.\n// If the CA bundle is empty, it validates using the default http client using the OS CA bundle.\n// If the CA bundle is not empty but does not contain any valid certs, it validates using\n// an empty CA bundle (which will always fail).\n// If valid cert+key paths can be loaded from the provided paths, they are used for client cert auth.\nfunc GetHTTPClient(cacerts []byte, certFile, keyFile string, options ...any) *http.Client {\n\tif len(cacerts) == 0 {\n\t\treturn defaultClient","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/clientaccess/token.go#L233-L269","documentation":"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.","triggerScenarios":"Tokens like `K10::<user>:` (empty password after the colon), `K10::justarandomstring`, or credentials where the '::' vs ':' separators got collapsed/reordered during transcription.","commonSituations":"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.","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"],"exampleFix":"# before (empty password / malformed creds)\nK10::<hash>::admin:\n\n# after\nK10::<hash>::abcdef.0123456789abcdef","handlingStrategy":"validation","validationCode":"creds := tokenAfterHashSegment // part after '::'\nbootstrap := regexp.MustCompile(`^[a-z0-9]{6}\\.[a-z0-9]{16}$`)\nbasic := regexp.MustCompile(`^[^:\\s]+:.+$`)\nif !bootstrap.MatchString(creds) && !basic.MatchString(creds) {\n    return fmt.Errorf(\"invalid token format: %q\", creds)\n}","typeGuard":"func isK3sCredsSegment(creds string) bool {\n    bootstrap := regexp.MustCompile(`^[a-z0-9]{6}\\.[a-z0-9]{16}$`)\n    basic := regexp.MustCompile(`^[^:\\s]+:.+$`)\n    return bootstrap.MatchString(creds) || basic.MatchString(creds)\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"invalid token format\") {\n    return fmt.Errorf(\"join token malformed; regenerate with `k3s token create` on the seed server\")\n}","preventionTips":["Never hand-assemble tokens from parts","Regenerate rather than repair suspect tokens","Keep token-producing automation (k3s token create) as the single source"],"tags":["token","validation","format","clientaccess"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}