{"record":{"id":"f872f5b86da68946","repo":"tymondesigns/jwt-auth","slug":"wrong-number-of-segments","errorCode":null,"errorMessage":"Wrong number of segments","messagePattern":"Wrong number of segments","errorType":"exception","errorClass":"Tymon\\JWTAuth\\Exceptions\\TokenInvalidException","httpStatus":null,"severity":"error","filePath":"src/Validators/TokenValidator.php","lineNumber":40,"sourceCode":"     * @return string\n     */\n    public function check($value)\n    {\n        return $this->validateStructure($value);\n    }\n\n    /**\n     * @param  string  $token\n     * @return string\n     *\n     * @throws \\Tymon\\JWTAuth\\Exceptions\\TokenInvalidException\n     */\n    protected function validateStructure($token)\n    {\n        $parts = explode('.', $token);\n\n        if (count($parts) !== 3) {\n            throw new TokenInvalidException('Wrong number of segments');\n        }\n\n        $parts = array_filter(array_map('trim', $parts));\n\n        if (count($parts) !== 3 || implode('.', $parts) !== $token) {\n            throw new TokenInvalidException('Malformed token');\n        }\n\n        return $token;\n    }\n}\n","sourceCodeStart":22,"sourceCodeEnd":52,"githubUrl":"https://github.com/tymondesigns/jwt-auth/blob/6c70930a92710d97e8e52b182fca2176097f33be/src/Validators/TokenValidator.php#L22-L52","documentation":"Thrown by TokenValidator::validateStructure() (via new Token($value) / TokenValidator::check) when the input string split on '.' does not yield exactly three segments. It is the first structural gate before parsing: a JWT must be header.payload.signature, so the value presented is not even shaped like a JWT.","triggerScenarios":"Passing a value with no dots (the literal strings 'null', 'undefined', 'Bearer', a database id) or too many dots (a JWE token with 5 parts, a doubly-joined token) to JWTAuth::parseToken(), auth:api middleware, or JWTAuth::getToken()->get(). Typically the Authorization header, query param, or cookie contained something other than a JWT.","commonSituations":"Frontend sends 'Authorization: Bearer undefined' or 'Bearer null' because the auth store was empty at request time; token variable never set before an API call; client sends the whole 'Bearer <token>' string including the scheme as the token value; passing a Laravel encrypted-cookie value or an opaque session id where a JWT was expected.","solutions":["Log the raw Authorization header (or parser input source) and confirm what is actually being sent - in most cases it is 'undefined', 'null', or empty","Fix the client so it only attaches a real token: check the token exists before setting the header (if (token) ...), and send only the token after 'Bearer ', never the scheme itself","If the client legitimately has no token, let it hit your guest flow instead of attaching a garbage header","Check the configured input parsers (config 'parsers' order: Authorization header, query string, cookie) - a stale query param or cookie can override the good header on routes where you didn't expect it"],"exampleFix":"// before - axios interceptor attaches whatever is in storage, even undefined\naxios.interceptors.request.use(cfg => { cfg.headers.Authorization = 'Bearer ' + store.token; return cfg; });\n\n// after - only attach when a token exists\naxios.interceptors.request.use(cfg => {\n  if (store.token) cfg.headers.Authorization = 'Bearer ' + store.token;\n  return cfg;\n});","handlingStrategy":"type-guard","validationCode":"// Reject non-JWT-shaped input at the boundary before the parser stack runs\nfunction looksLikeJwt(?string $token): bool\n{\n    return $token !== null\n        && substr_count($token, '.') === 2\n        && preg_match('/^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/', $token) === 1;\n}\n\n// usage\nif (!looksLikeJwt($request->bearerToken())) {\n    return response()->json(['error' => 'token_not_provided'], 401);\n}","typeGuard":"function looksLikeJwt(?string $token): bool\n{\n    return is_string($token)\n        && preg_match('/^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/', $token) === 1;\n}","tryCatchPattern":"use Tymon\\JWTAuth\\Exceptions\\TokenInvalidException;\n\ntry {\n    $user = auth('api')->parseToken()->authenticate();\n} catch (TokenInvalidException $e) {\n    return response()->json(['error' => 'token_invalid'], 401);\n}","preventionTips":["On the client, attach the Authorization header only when a token is actually present (guard against 'undefined'/'null' stringification)","Send the raw token after 'Bearer ' - never the whole header string, never urlencoded","Log the raw bearer value when this fires; the segment count tells you immediately whether the client sent garbage"],"tags":["jwt","php","laravel","token-format","input-validation","api-clients"],"backgroundTag":"jwt-malformed-token","analyzedSha":"6c70930a92710d97e8e52b182fca2176097f33be","analyzedAt":"2026-08-21T02:16:37.040Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}