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

HasClaimWithValue first checks the claim exists; if the claim key is absent from the token's claim set it throws ConstraintViolation 'The token does not have the claim ...'. This happens before any value comparison.

Solutions

  1. Ensure the issuer always emits the claim
  2. Fix claim-name typos so issuer and validator agree
  3. Catch ConstraintViolation and handle absence explicitly if the claim is optional

Example fix

// before
{"sub": "123"}
// after
{"sub": "123", "role": "admin"}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!$token->claims()->has('role')) {
    // handle absence before value assertion
}

Try / catch

try {
    $validator->assert($token, new HasClaimWithValue('role', 'admin'));
} catch (RequiredConstraintsViolated $e) {
    // claim missing; reject or degrade
}

Prevention

When it happens

Trigger: (new HasClaimWithValue('role', 'admin'))->assert($plainToken) where the claim 'role' is not present in $plainToken->claims().

Common situations: Legacy tokens issued before the claim was introduced; tokens from a different issuer/tenant that omit the claim; typo in the claim name between issuer and validator.

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


AI-assisted analysis of lcobucci/jwt@375813049c (2026-09-14). Data as JSON: /api/errors/08fd5825909e3b58. Report an issue: GitHub.

Appendix: source

Thrown at src/Validation/Constraint/HasClaimWithValue.php:32

{
    /** @param non-empty-string $claim */
    public function __construct(private string $claim, private mixed $expectedValue)
    {
        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);
        }

        if ($claims->get($this->claim) !== $this->expectedValue) {
            throw ConstraintViolation::error(
                'The claim "' . $this->claim . '" does not have the expected value',
                $this,
            );
        }
    }
}

View on GitHub (pinned to 375813049c)