tymondesigns/jwt-auth · error · Tymon\JWTAuth\Exceptions\TokenInvalidException
Malformed token
Error message
Malformed token
What it means
Thrown by TokenValidator::validateStructure() when the string has three dot-separated segments but they are not clean non-empty base64url bodies: after trim() and removal of empty segments the count changes, or rejoining the trimmed parts no longer reproduces the original. Concretely, at least one segment is empty (e.g. 'header..signature') or contains whitespace/line breaks inside it.
Source
Thrown at src/Validators/TokenValidator.php:46
/**
* @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 received token wrapped in delimiters (e.g. "[$token]") to reveal invisible whitespace or embedded newlines
- Strip surrounding whitespace on the server before parsing if the transport adds it: $token = preg_replace('/\s+/', '', $token) - but fix the producer if whitespace appears inside the token
- Regenerate/re-login to obtain a clean token if the stored one was wrapped or truncated
- If you control the client, ensure the token is transmitted as a single line with no formatting applied (no word-wrap, no pretty-printing in storage)
Example fix
// before - token wrapped across lines in transit
"eyJhbGciOi...\neyJzdWIi...\n.E-mSig" // TokenInvalidException: Malformed token
// after - normalize at the boundary, then parse
$token = preg_replace('/\s+/', '', $request->bearerToken());
$user = JWTAuth::parseToken()->authenticate(); Defensive patterns
Strategy: type-guard
Validate before calling
// Same strict shape check also rejects empty segments and embedded whitespace
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;
}
// optionally normalize transport noise first
$token = preg_replace('/\s+/', '', (string) $request->bearerToken()); 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) {
// 'Malformed token' = structurally broken input; 401 and let the client re-authenticate
return response()->json(['error' => 'token_malformed'], 401);
} Prevention
- Store and transmit JWTs as a single line - never wrap, pretty-print, or HTML-encode them
- When logging tokens, wrap in delimiters ("[$token]") so invisible whitespace is visible in logs
- Strip whitespace at the API boundary with preg_replace('/\\s+/', '', $token) if intermediaries fold headers
- Treat a malformed-token spike as a transport regression - check proxies, copy-paste flows, and storage columns for truncation
When it happens
Trigger: Passing a token where the payload or signature segment is empty, or where any segment carries leading/trailing spaces, tabs, or embedded newlines - e.g. a token wrapped across lines by an email client, a header value folded by a proxy, or a copy-paste that introduced a space. Caught in TokenValidator::check, reached from new Token($value) inside JWTAuth::parseToken()->authenticate().
Common situations: Token truncated or wrapped to multiple lines before being sent; whitespace sneaking in through copy-paste or template interpolation; a client sending a two-part unsigned JWT ('header.payload.') which has an empty signature segment; middleware or proxies re-encoding the Authorization header; a token stored in a database TEXT column with a trailing newline.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Wrong number of segments
- 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/48823658d967e5cd.
Report an issue: GitHub.