{"record":{"id":"31d92277595ef265","repo":"lcobucci/jwt","slug":"the-token-is-expired-strictvalidat","errorCode":null,"errorMessage":"The token is expired","messagePattern":"The token is expired","errorType":"validation","errorClass":"ConstraintViolation","httpStatus":null,"severity":"error","filePath":"src/Validation/Constraint/StrictValidAt.php","lineNumber":57,"sourceCode":"            throw ConstraintViolation::error('You should pass a plain token', $this);\n        }\n\n        $now = $this->clock->now();\n\n        $this->assertIssueTime($token, $now->add($this->leeway));\n        $this->assertMinimumTime($token, $now->add($this->leeway));\n        $this->assertExpiration($token, $now->sub($this->leeway));\n    }\n\n    /** @throws ConstraintViolation */\n    private function assertExpiration(UnencryptedToken $token, DateTimeInterface $now): void\n    {\n        if (! $token->claims()->has(Token\\RegisteredClaims::EXPIRATION_TIME)) {\n            throw ConstraintViolation::error('\"Expiration Time\" claim missing', $this);\n        }\n\n        if ($token->isExpired($now)) {\n            throw ConstraintViolation::error('The token is expired', $this);\n        }\n    }\n\n    /** @throws ConstraintViolation */\n    private function assertMinimumTime(UnencryptedToken $token, DateTimeInterface $now): void\n    {\n        if (! $token->claims()->has(Token\\RegisteredClaims::NOT_BEFORE)) {\n            throw ConstraintViolation::error('\"Not Before\" claim missing', $this);\n        }\n\n        if (! $token->isMinimumTimeBefore($now)) {\n            throw ConstraintViolation::error('The token cannot be used yet', $this);\n        }\n    }\n\n    /** @throws ConstraintViolation */\n    private function assertIssueTime(UnencryptedToken $token, DateTimeInterface $now): void\n    {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/lcobucci/jwt/blob/375813049c24c7111bda8b6884c57b071ceb2fe7/src/Validation/Constraint/StrictValidAt.php#L39-L75","documentation":"StrictValidAt's assertExpiration also verifies the token has not passed its 'exp' time using $token->isExpired($now). If the current time (plus configured leeway) is past exp, it throws 'The token is expired'. This is the canonical expired-JWT rejection in strict validation.","triggerScenarios":"Validator::assert($token, new StrictValidAt(...)) where the token's exp claim is earlier than now->add(leeway) — i.e. the token's lifetime has elapsed.","commonSituations":"Cached/stored tokens used past their lifetime; long-running jobs holding a token across expiration; server clock differences between issuer and verifier beyond the configured leeway; users returning to an app with an old session token.","solutions":["Refresh the token before use (refresh-token flow) and retry with the new token","Increase leeway in StrictValidAt only if the issue is genuine minor clock skew, not real expiry","Obtain a fresh token by re-authenticating if no refresh mechanism exists","Check server clocks (NTP) if expiry appears prematurely relative to issuer expectations"],"exampleFix":"// before\n$validator->assert($oldToken, new StrictValidAt(new SystemClock::fromUTC()));\n// after (refresh first)\n$newToken = $auth->refresh($oldToken);\n$validator->assert($newToken, new StrictValidAt(new SystemClock::fromUTC()));","handlingStrategy":"try-catch","validationCode":"if ($token->claims()->has('exp') && $token->isExpired((new DateTimeImmutable())->add($leeway))) {\n    // refresh before validating\n}","typeGuard":"null","tryCatchPattern":"try {\n    $validator->assert($token, new StrictValidAt($clock, $leeway));\n} catch (ConstraintViolation $e) {\n    if ($e->getMessage() === 'The token is expired') { $token = $auth->refresh($refreshToken); }\n}","preventionTips":["Refresh tokens proactively before their exp, not lazily after failure","Set leeway to absorb acceptable clock skew (e.g. PT30S-PT5M)","Never cache tokens longer than their lifetime"],"tags":["jwt","token-expired","validation","clock"],"backgroundTag":"jwt-token-expired","analyzedSha":"375813049c24c7111bda8b6884c57b071ceb2fe7","analyzedAt":"2026-09-14T11:12:28.004Z","contentChangedAt":"2026-09-14T11:12:28.004Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}