lcobucci/jwt · error · ConstraintViolation
The token was not issued by the given issuers
Error message
The token was not issued by the given issuers
What it means
This ConstraintViolation is thrown by the IssuedBy validation constraint. It fires when the token's `iss` (issuer) claim is missing or is not one of the issuer values configured in the constraint. The library throws it so applications can reject tokens minted by an authority they do not trust.
Solutions
- Ensure tokens are minted with ->issuedBy('https://your-issuer.example.com') matching the configured value exactly.
- Pass every acceptable issuer to the constraint: IssuedBy::constraint('https://old-issuer', 'https://new-issuer').
- Compare the token's `iss` ($token->claims()->get('iss')) with the configured issuers byte-for-byte (scheme, host, path, no trailing slash difference).
- If issuer verification is not required for this use case, drop the IssuedBy constraint from the validator configuration.
Example fix
// before: issuer mismatch (trailing slash)
$constraint = new IssuedBy('https://issuer.example.com/');
// after: exact issuer as embedded in the token
$constraint = new IssuedBy('https://issuer.example.com'); Defensive patterns
Strategy: try-catch
Validate before calling
$iss = $token->claims()->get('iss');
if (! is_string($iss) || ! in_array($iss, $allowedIssuers, true)) {
// reject before calling the constraint
} Type guard
function issuedByAllowed(Lcobucci\JWT\Token $token, array $allowedIssuers): bool
{
$iss = $token->claims()->get('iss');
return is_string($iss) && in_array($iss, $allowedIssuers, true);
} Try / catch
try {
$validator->assert($token, $constraints);
} catch (Lcobucci\JWT\Validation\ConstraintViolation $e) {
if ($e->getConstraint() instanceof Lcobucci\JWT\Validation\Constraint\IssuedBy) {
// untrusted issuer: reject with 401
}
} Prevention
- Keep the list of trusted issuers in configuration and pass all of them to IssuedBy.
- Normalize issuer URLs (no trailing slash, consistent scheme) at issuance and validation time.
- When migrating issuer domains, accept old and new issuers during a transition window.
- Mint tokens with ->issuedBy() using the exact same string you validate against.
When it happens
Trigger: Calling IssuedByConstraint::assert($token) where Token::hasBeenIssuedBy(...$this->issuers) returns false — the token has no `iss` claim, or its `iss` value/type does not exactly match any of the issuer strings given to the constraint's constructor.
Common situations: Multi-tenant setups where each tenant issues tokens with a different `iss` but validation uses a single hard-coded issuer; issuer URLs mismatched by trailing slash, scheme (http vs https) or case; migrating the issuer identifier (e.g. new domain) while old tokens are still in circulation; tokens built without ->issuedBy(...) at all.
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 is not identified with the expected ID
- The token is expired
- The token cannot be used yet
- No constraint given.
- Error while encoding to JSON
AI-assisted analysis of lcobucci/jwt@375813049c (2026-09-14).
Data as JSON: /api/errors/6a6ae9ad76d44e35.
Report an issue: GitHub.
Appendix: source
Thrown at src/Validation/Constraint/IssuedBy.php:24
use Lcobucci\JWT\Token;
use Lcobucci\JWT\Validation\Constraint;
use Lcobucci\JWT\Validation\ConstraintViolation;
final readonly class IssuedBy implements Constraint
{
/** @var non-empty-string[] */
private array $issuers;
/** @param non-empty-string ...$issuers */
public function __construct(string ...$issuers)
{
$this->issuers = $issuers;
}
public function assert(Token $token): void
{
if (! $token->hasBeenIssuedBy(...$this->issuers)) {
throw ConstraintViolation::error(
'The token was not issued by the given issuers',
$this,
);
}
}
}
View on GitHub (pinned to 375813049c)