tymondesigns/jwt-auth · error · Tymon\JWTAuth\Exceptions\TokenInvalidException
Wrong number of segments
Error message
Wrong number of segments
What it means
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.
Source
Thrown at src/Validators/TokenValidator.php:40
* @return string
*/
public function check($value)
{
return $this->validateStructure($value);
}
/**
* @param string $token
* @return string
*
* @throws \Tymon\JWTAuth\Exceptions\TokenInvalidException
*/
protected function validateStructure($token)
{
$parts = explode('.', $token);
if (count($parts) !== 3) {
throw new TokenInvalidException('Wrong number of segments');
}
$parts = array_filter(array_map('trim', $parts));
if (count($parts) !== 3 || implode('.', $parts) !== $token) {
throw new TokenInvalidException('Malformed token');
}
return $token;
}
}
View on GitHub (pinned to 6c70930a92)
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
Example fix
// before - axios interceptor attaches whatever is in storage, even undefined
axios.interceptors.request.use(cfg => { cfg.headers.Authorization = 'Bearer ' + store.token; return cfg; });
// after - only attach when a token exists
axios.interceptors.request.use(cfg => {
if (store.token) cfg.headers.Authorization = 'Bearer ' + store.token;
return cfg;
}); Defensive patterns
Strategy: type-guard
Validate before calling
// Reject non-JWT-shaped input at the boundary before the parser stack runs
function looksLikeJwt(?string $token): bool
{
return $token !== null
&& substr_count($token, '.') === 2
&& preg_match('/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/', $token) === 1;
}
// usage
if (!looksLikeJwt($request->bearerToken())) {
return response()->json(['error' => 'token_not_provided'], 401);
} Type guard
function looksLikeJwt(?string $token): bool
{
return is_string($token)
&& preg_match('/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/', $token) === 1;
} Try / catch
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
try {
$user = auth('api')->parseToken()->authenticate();
} catch (TokenInvalidException $e) {
return response()->json(['error' => 'token_invalid'], 401);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Malformed token
- Could not create token: {exception message}
- Could not decode token: {exception message}
- Token Signature could not be verified.
- The given algorithm could not be found
AI-assisted analysis of tymondesigns/jwt-auth@6c70930a92 (2026-08-21).
Data as JSON: /api/errors/f872f5b86da68946.
Report an issue: GitHub.