lcobucci/jwt · error · ConstraintViolation
"Not Before" claim missing
Error message
"Not Before" claim missing
What it means
StrictValidAt requires the 'nbf' (Not Before) registered claim to be present and asserts it, because strict mode treats all three time claims (iat, nbf, exp) as mandatory. If the claim set lacks nbf, assertMinimumTime throws '"Not Before" claim missing' without evaluating token usability.
Solutions
- Fix the issuer to include ->canOnlyBeUsedAfter($now) (nbf) when building tokens
- Use a validator variant that does not require all claims if strictness is not required for your profile
- Add a claims()->has('nbf') pre-check at the trust boundary and surface a clearer rejection reason
- Coordinate the validator upgrade with reissuance of tokens that include nbf
Example fix
// before
$builder->issuedAt($now)->expiresAt($now->modify('+1 hour'));
// after
$builder->issuedAt($now)->canOnlyBeUsedAfter($now)->expiresAt($now->modify('+1 hour')); Defensive patterns
Strategy: validation
Validate before calling
if (! $token->claims()->has('nbf')) {
throw new InvalidArgumentException('Token must carry nbf claim for StrictValidAt');
} Type guard
function hasNotBeforeClaim(UnencryptedToken $t): bool { return $t->claims()->has('nbf'); } Try / catch
try {
$validator->assert($token, new StrictValidAt($clock));
} catch (ConstraintViolation $e) {
if (str_contains($e->getMessage(), '"Not Before" claim missing')) { /* reject; fix issuer */ }
} Prevention
- Standardize token creation on a helper that always sets iat/nbf/exp
- When upgrading to strict validation, reissue or reject legacy tokens missing nbf
When it happens
Trigger: Validator::assert($token, new StrictValidAt(...)) on a token built without ->canOnlyBeUsedAfter() (or otherwise without the nbf claim).
Common situations: Minimal token issuers that only set iat/exp; third-party-issued JWTs that omit nbf; migrating from a lenient validator to StrictValidAt and older tokens lacking nbf suddenly rejected.
Related errors
- "Expiration Time" claim missing
- The token does not have the claim
- The token does not have the claim
- "Issued At" claim missing
- No constraint given.
AI-assisted analysis of lcobucci/jwt@375813049c (2026-09-14).
Data as JSON: /api/errors/9a75fb7fcac96048.
Report an issue: GitHub.
Appendix: source
Thrown at src/Validation/Constraint/StrictValidAt.php:65
}
/** @throws ConstraintViolation */
private function assertExpiration(UnencryptedToken $token, DateTimeInterface $now): void
{
if (! $token->claims()->has(Token\RegisteredClaims::EXPIRATION_TIME)) {
throw ConstraintViolation::error('"Expiration Time" claim missing', $this);
}
if ($token->isExpired($now)) {
throw ConstraintViolation::error('The token is expired', $this);
}
}
/** @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)