lcobucci/jwt · error · RequiredConstraintsViolated

Required constraints violated

Error message

Required constraints violated

What it means

This is lcobucci/jwt's aggregate validation error. Validator::assert runs each given constraint against the token, collecting ConstraintViolation objects; if any constraint failed, it throws RequiredConstraintsViolated::fromViolations(...). This exception (a subclass of the constraint-violation family) carries all individual violations, unlike Validator::validate() which returns false silently.

Solutions

  1. Catch lcobucci\jwt\Validation\RequiredConstraintsViolated and call getViolations() to see which constraint(s) actually failed before deciding on a fix.
  2. Verify the signing key/signer passed to SignedWith matches the one used to sign the token (algorithm and key material).
  3. Check the token's time claims: ensure exp is in the future, iat/nbf are not in the future relative to your clock, and enable leeway (DateInterval) if clock skew exists.
  4. Re-derive or re-issue the token if required claims (aud, jti, sub, custom constraints) don't match expectations; use UnsupportedHeaderExceptions/constraint unit tests to validate your constraint set.

Example fix

// before
$validator->assert($token, new SignedWith($signer, $key)); // generic 'Required constraints violated'

// after
try {
    $validator->assert($token, new SignedWith($signer, $key), new StrictValidAt($clock));
} catch (RequiredConstraintsViolated $e) {
    foreach ($e->getViolations() as $violation) {
        error_log($violation->getMessage()); // e.g. 'The token was issued in the future'
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check constraints yourself and log which one would fail
$violations = [];
$validator = new Lcobucci\JWT\Validation\Validator();
foreach ($constraints as $constraint) {
    if (!$constraint->assert($token)) { // validate() variant collects instead of throwing
        $violations[] = get_class($constraint);
    }
}
// if $violations is non-empty, assert() would throw RequiredConstraintsViolated

Type guard

function passesAllConstraints(Lcobucci\JWT\Token $token, Lcobucci\JWT\Validation\Validator $v, Lcobucci\JWT\Validation\Constraint ...$constraints): bool
{
    return $v->validate($token, ...$constraints); // validate() returns bool, never throws
}

Try / catch

use Lcobucci\JWT\Validation\RequiredConstraintsViolated;

try {
    $validator->assert($token, ...$constraints);
} catch (RequiredConstraintsViolated $e) {
    foreach ($e->getViolations() as $violation) {
        // inspect $violation->getMessage() to branch on expired/signature/claims failures
    }
}

Prevention

When it happens

Trigger: Any call to (new Validator())->assert($token, ...constraints...) where at least one constraint produces a violation: e.g. assert($token, new SignedWith($signer, $key)) with a wrong key, StrictValidAt with a future iat or expired exp, IdentifiedBy with a mismatching jti, or an empty/failed constraint set — the exception wraps the underlying ConstraintViolation(s) and its message stays generic ('Required constraints violated') while details live on getViolations().

Common situations: Verifying tokens signed with a rotated/changed secret key; expired or not-yet-valid tokens checked with StrictValidAt/ValidAt; tokens missing required claims (iat, exp, jti); migrating library versions where claim handling became stricter (e.g. lcobucci/jwt 4.x/5.x behavior changes); callers inspecting only the top-level message instead of getViolations().

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/562e76a2c2a27351. Report an issue: GitHub.

Appendix: source

Thrown at src/Validation/Validator.php:23

use Lcobucci\JWT\Token;

final readonly class Validator implements \Lcobucci\JWT\Validator
{
    public function assert(Token $token, Constraint ...$constraints): void
    {
        if ($constraints === []) {
            throw new NoConstraintsGiven('No constraint given.');
        }

        $violations = [];

        foreach ($constraints as $constraint) {
            $this->checkConstraint($constraint, $token, $violations);
        }

        if ($violations !== []) {
            throw RequiredConstraintsViolated::fromViolations(...$violations);
        }
    }

    /** @param ConstraintViolation[] $violations */
    private function checkConstraint(
        Constraint $constraint,
        Token $token,
        array &$violations,
    ): void {
        try {
            $constraint->assert($token);
        } catch (ConstraintViolation $e) {
            $violations[] = $e;
        }
    }

    public function validate(Token $token, Constraint ...$constraints): bool
    {

View on GitHub (pinned to 375813049c)