mastra-ai/mastra · error
Invalid token
Error message
Invalid token
What it means
getTokenIssuer decodes an access token's issuer (iss claim) and throws 'Invalid token' when jwt.decode returned null — meaning the string could not be decoded as a JWT at all (malformed structure, not three dot-separated base64 segments, or undecodable payload). Related sibling throws cover a missing/non-object payload ('Invalid token payload') and a missing iss ('Invalid token header').
Source
Thrown at packages/auth/src/utils.ts:12
import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
export type JwtPayload = jwt.JwtPayload;
export async function decodeToken(accessToken: string) {
const decoded = jwt.decode(accessToken, { complete: true });
return decoded;
}
export function getTokenIssuer(decoded: jwt.JwtPayload | null) {
if (!decoded) throw new Error('Invalid token');
if (!decoded.payload || typeof decoded.payload !== 'object') throw new Error('Invalid token payload');
if (!decoded.payload.iss) throw new Error('Invalid token header');
return decoded.payload.iss;
}
export async function verifyHmac(accessToken: string, secret: string) {
const decoded = jwt.decode(accessToken, { complete: true });
if (!decoded) throw new Error('Invalid token');
return jwt.verify(accessToken, secret) as jwt.JwtPayload;
}
export async function verifyJwks(accessToken: string, jwksUri: string) {
const decoded = jwt.decode(accessToken, { complete: true });
if (!decoded) throw new Error('Invalid token');
View on GitHub (pinned to 75dd419e61)
Solutions
- Log/inspect the raw accessToken received — confirm it looks like header.payload.signature
- Fix the client/sender to transmit a real JWT (correct token type in the Authorization header)
- Check for truncation/corruption in transit (headers split, whitespace, URL encoding issues)
- Before calling, guard: const d = await decodeToken(t); if (!d) handle invalid token instead of throwing
Example fix
// before
const issuer = await getTokenIssuer(await decodeToken(token));
// after
const decoded = await decodeToken(token);
if (!decoded) throw new UnauthorizedError('Malformed token');
const issuer = getTokenIssuer(decoded); Defensive patterns
Strategy: type-guard
Validate before calling
/^eyJ[\w-]+\.[\w-]+\.[\w-]*$/.test(token) // quick 3-part JWT shape check before decodeToken
export function looksLikeJwt(t: string) { return /^eyJ[\w-]+\.[\w-]+\.[\w-]*$/.test(t); } Type guard
export function isDecodedJwt(d: jwt.JwtPayload | null): d is jwt.JwtPayload {
return d != null && typeof d === 'object' && typeof d.iss === 'string';
}
const decoded = await decodeToken(token);
if (!isDecodedJwt(decoded)) throw new UnauthorizedError('Malformed or non-JWT credential'); Try / catch
try {
const issuer = await getTokenIssuer(await decodeToken(token));
} catch (e) {
if (e instanceof Error && e.message === 'Invalid token') {
// token did not decode: return 401 'malformed token' instead of a 500
}
throw e;
} Prevention
- Pre-check tokens with a 3-segment shape regex before decoding
- Ensure clients send a real JWT, not opaque keys, in the Authorization header
- Guard headers from truncation/corruption in proxies and gateways
- Return 401 (client error) rather than letting this become a 500 on the server
When it happens
Trigger: Calling getTokenIssuer(decodeToken(accessToken)) where accessToken is not a valid JWT: garbage/truncated string, opaque token (e.g. a random API key), a token that was URL-corrupted, or decoding a token type jsonwebtoken's decode cannot parse.
Common situations: Clients sending the wrong credential type in the Authorization header, copy/paste truncation of tokens, tokens mangled by proxies/logging, or expecting an id_token but receiving an opaque refresh token.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Kimi For Coding token ${operation} response missing fields
- Failed to extract ChatGPT account id from OpenAI Codex token
- JWT auth secret is required
- Invalid token payload
- Invalid token header
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/01d874fc53a9408d.
Report an issue: GitHub.