lcobucci/jwt · error · Lcobucci\JWT\Validation\ConstraintViolation
The token does not have the claim
Error message
The token does not have the claim "{claim}" What it means
HasClaim asserts that the token contains the given custom claim; if the claim set has no such key, it throws ConstraintViolation with this message. It signals the expected claim is missing, not that its value was wrong.
Solutions
- Update the token issuer to always include the required claim
- Make the constraint optional / use Validator::assert multiple times with fallback handling
- Catch ConstraintViolation and treat missing claim as a valid-but-unprivileged token if the claim is truly optional
Example fix
// before (token payload lacking claim)
{"sub": "123"}
// after
{"sub": "123", "role": "admin"} Defensive patterns
Strategy: try-catch
Validate before calling
if (!$token instanceof UnencryptedToken || !$token->claims()->has('role')) {
// handle missing claim before asserting
} Try / catch
try {
$validator->assert($token, new HasClaim('role'));
} catch (RequiredConstraintsViolated $e) {
// claim absent; treat as unprivileged or reject
} Prevention
- Ensure the issuer always includes required custom claims
- Version your token schema and reject legacy tokens
- Catch ConstraintViolation to distinguish missing vs wrong value
When it happens
Trigger: (new HasClaim('role'))->assert($plainToken) where $plainToken->claims() does not contain the key 'role'.
Common situations: Tokens issued by an older version of the issuer that didn't add the claim yet; per-client tokens missing optional claims; environment-specific tokens (staging vs production issuers).
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- The token does not have the claim
- The claim " " does not have the expected value
- "Expiration Time" claim missing
- "Not Before" claim missing
- "Issued At" claim missing
AI-assisted analysis of lcobucci/jwt@375813049c (2026-09-14).
Data as JSON: /api/errors/74de05070138be22.
Report an issue: GitHub.
Appendix: source
Thrown at src/Validation/Constraint/HasClaim.php:32
{
/** @param non-empty-string $claim */
public function __construct(private string $claim)
{
if (in_array($claim, Token\RegisteredClaims::ALL, true)) {
throw CannotValidateARegisteredClaim::create($claim);
}
}
public function assert(Token $token): void
{
if (! $token instanceof UnencryptedToken) {
throw ConstraintViolation::error('You should pass a plain token', $this);
}
$claims = $token->claims();
if (! $claims->has($this->claim)) {
throw ConstraintViolation::error('The token does not have the claim "' . $this->claim . '"', $this);
}
}
}
View on GitHub (pinned to 375813049c)