lcobucci/jwt · error · ConstraintViolation
"Issued At" claim missing
Error message
"Issued At" claim missing
What it means
StrictValidAt mandates the 'iat' (Issued At) claim; assertIssueTime throws '"Issued At" claim missing' when the claim set has no iat. Strict mode deliberately rejects tokens without issuance timestamps to prevent accepting tokens of unknown provenance.
Solutions
- Fix the issuer to always call ->issuedAt(new DateTimeImmutable(...)) when building tokens
- Use a less strict validator if your token profile does not guarantee iat
- Pre-check $token->claims()->has('iat') and reject with an explicit 'token missing iat' error at the boundary
- Reissue legacy tokens that predate the iat requirement
Example fix
// before
$builder->expiresAt($now->modify('+1 hour'));
// after
$builder->issuedAt($now)->expiresAt($now->modify('+1 hour')); Defensive patterns
Strategy: validation
Validate before calling
if (! $token->claims()->has('iat')) {
throw new InvalidArgumentException('Token must carry iat claim for StrictValidAt');
} Type guard
function hasIssuedAtClaim(UnencryptedToken $t): bool { return $t->claims()->has('iat'); } Try / catch
try {
$validator->assert($token, new StrictValidAt($clock));
} catch (ConstraintViolation $e) {
if (str_contains($e->getMessage(), '"Issued At" claim missing')) { /* reject; fix issuer */ }
} Prevention
- Always set iat in your token builder wrapper
- Validate third-party tokens for required claims before running strict validators
- Include iat/nbf/exp requirements in API contracts with token issuers
When it happens
Trigger: Validator::assert($token, new StrictValidAt(...)) on a token created without ->issuedAt(...) — the RegisteredClaims::ISSUED_AT claim is absent.
Common situations: Old token builders that only set exp; tokens minted by external systems that omit iat; moving from LooseValidAt/lenient checks to StrictValidAt causing legacy tokens to fail; test fixtures handcrafted without iat.
Related errors
- The token does not have the claim
- The token does not have the claim
- "Expiration Time" claim missing
- "Not Before" claim missing
- No constraint given.
AI-assisted analysis of lcobucci/jwt@375813049c (2026-09-14).
Data as JSON: /api/errors/b95bd4dbd115cbd8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Validation/Constraint/StrictValidAt.php:77
}
/** @throws ConstraintViolation */
private function assertMinimumTime(UnencryptedToken $token, DateTimeInterface $now): void
{
if (! $token->claims()->has(Token\RegisteredClaims::NOT_BEFORE)) {
throw ConstraintViolation::error('"Not Before" claim missing', $this);
}
if (! $token->isMinimumTimeBefore($now)) {
throw ConstraintViolation::error('The token cannot be used yet', $this);
}
}
/** @throws ConstraintViolation */
private function assertIssueTime(UnencryptedToken $token, DateTimeInterface $now): void
{
if (! $token->claims()->has(Token\RegisteredClaims::ISSUED_AT)) {
throw ConstraintViolation::error('"Issued At" claim missing', $this);
}
if (! $token->hasBeenIssuedBefore($now)) {
throw ConstraintViolation::error('The token was issued in the future', $this);
}
}
}
View on GitHub (pinned to 375813049c)