ecdsa.com
jose (JavaScript)JWT libraries

Error message

"exp" claim timestamp check failed

jose (JavaScript) — JWTExpired, code ERR_JWT_EXPIRED

What it means

jose's claim validation rejected the token because its exp timestamp is in the past relative to the verifier's clock. The signature check had already passed — this is purely a freshness failure. jose raises the same wording pattern for other claims ("nbf" claim timestamp check failed) when a token is used before its not-before time.

Why it happens

How to fix it

  1. 1.

    Add bounded clock tolerance

    jose accepts a clockTolerance option (number of seconds or a human-readable string). Keep it small; it is a drift absorber, not a lifetime extension.

    js
    import { jwtVerify } from "jose";
    
    await jwtVerify(token, key, {
      algorithms: ["ES256"],
      clockTolerance: "30s",
    });
  2. 2.

    Print the timeline before changing anything

    Compare iat, exp and the verifier's now. The pattern tells you the cause: exp seconds in the past → refresh problem; exp before iat → issuing bug; exp ≈ now but failing → skew.

    js
    import { decodeJwt } from "jose";
    
    const { iat, exp } = decodeJwt(token);
    console.log({ iat: new Date(iat * 1000), exp: new Date(exp * 1000), now: new Date() });

Related errors

← Browse the full signature error database