NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
JWT for Laravel

Exceptions

RoundlyConsulting\Jwt\Jose\Exceptions\JwtException extends RuntimeException and is the base of every token error. Catch it to handle any failure uniformly, or a subclass for a precise cause:

ExceptionThrown when
JwtExceptionBase class — catch it to handle any token failure.
MalformedTokenNot three segments, invalid base64url, a header or payload that isn’t a JSON object, or a token over 8 KB.
AlgorithmMismatchThe header alg isn’t the pinned algorithm, or the key type doesn’t match it — blocks alg:none and RS256↔HS256 confusion.
InvalidSignatureThe RS256 or HS256 signature fails; also an unknown per-issuer service-token iss.
UnexpectedTokenTypeA typ header is present and isn’t JWT (RFC 8725 explicit typing).
UnencodableClaimsA claim can’t be serialised to JSON, e.g. non-UTF-8 bytes in an extra claim.
TokenExpiredexp, minus leeway, is in the past.
TokenNotYetValidnbf or iat is in the future beyond the leeway.
UnexpectedCriticalHeaderThe token carries a crit header.
ClaimMismatchA required claim is absent or mistyped; an iss/aud pin mismatch; service scope, audience or issuer checks.
KeyLoadFailedA key is missing, unreadable, not RSA, under 2048 bits, or its path isn’t configured.
EmptySecretAn HMAC secret is empty.
PemAsHmacSecretA PEM-encoded key was passed as an HMAC secret.
WeakSecretAn HMAC secret is under 32 bytes, a single repeated byte, or carries raw DER key material.
use RoundlyConsulting\Jwt\Facades\Jwt;
use RoundlyConsulting\Jwt\Jose\Exceptions\JwtException;
use RoundlyConsulting\Jwt\Jose\Exceptions\TokenExpired;

try {
    $claims = Jwt::verify($jwt);
} catch (TokenExpired $e) {
    // Prompt a re-login / refresh flow.
} catch (JwtException $e) {
    // Any other token failure: 401.
}

Misconfiguration is a 500, not a 401

Both guards turn a JwtException into a null user — a 401. Operator errors must never take that path, so they are deliberately not JwtExceptions:

  • RoundlyConsulting\Jwt\Exceptions\JwtMisconfigured — an issuer or audience that is not set (null or blank), a guard name that isn’t a jwt guard, an uncallable token_version, a guard mintAccessToken() whose request names another audience, or a config value of the wrong shape — a TTL of five, an unparseable switch, a malformed service.secrets pair, an identity that isn’t a ClaimsAuthenticatable.
  • RoundlyConsulting\Jwt\ServiceTokens\Exceptions\ServiceAuthMisconfigured — a missing or weak service secret, no resolvable service name, no audience or own issuer on issue, a missing own entry in the per-issuer map, or reserved extra claims.
  • KeyLoadFailed is a JwtException, but the jwt guard rethrows it ahead of the generic handler — a missing or invalid RSA key is an operator error, not an unauthenticated caller.

KeyLoadFailed messages are actionable: they name the missing path and the fix, such as running jwt:generate-keys or setting the env var.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.