{"record":{"id":"0634d3f63bba6b42","repo":"lcobucci/jwt","slug":"constraint-violation-triggered-by-one-of-the-following-n","errorCode":null,"errorMessage":"Constraint Violation triggered by one of the following:\\n- <accumulated violation messages>","messagePattern":"Constraint Violation triggered by one of the following:\\\\n- <accumulated violation messages>","errorType":"validation","errorClass":"ConstraintViolation","httpStatus":null,"severity":"error","filePath":"src/Validation/Constraint/SignedWithOneInSet.php","lineNumber":36,"sourceCode":"    {\n        $this->constraints = $constraints;\n    }\n\n    public function assert(Token $token): void\n    {\n        $errorMessage = 'It was not possible to verify the signature of the token, reasons:';\n\n        foreach ($this->constraints as $constraint) {\n            try {\n                $constraint->assert($token);\n\n                return;\n            } catch (ConstraintViolation $violation) {\n                $errorMessage .= PHP_EOL . '- ' . $violation->getMessage();\n            }\n        }\n\n        throw ConstraintViolation::error($errorMessage, $this);\n    }\n}\n","sourceCodeStart":18,"sourceCodeEnd":39,"githubUrl":"https://github.com/lcobucci/jwt/blob/375813049c24c7111bda8b6884c57b071ceb2fe7/src/Validation/Constraint/SignedWithOneInSet.php#L18-L39","documentation":"SignedWithOneInSet wraps multiple SignedWith constraints and passes if at least one verifies the signature. If every constraint in the set throws ConstraintViolation, it re-throws a single ConstraintViolation whose message is 'Constraint Violation triggered by one of the following:' followed by each child violation message on its own line. This aggregates all failure reasons so the caller knows why each key/signer combination failed.","triggerScenarios":"Validator::assert($token, new SignedWithOneInSet(...$signedWithConstraints)) where none of the supplied SignedWith constraints verify the token signature — every child throws and the accumulated messages are bundled.","commonSituations":"Key rotation setups where the old and new keys are both listed but the token was signed with a third (revoked) key; multiple issuer keys configured but token came from an unlisted issuer; PEM public key content pasted incorrectly so all candidates fail.","solutions":["Read the accumulated '- ...' lines in the message to see which key/signer each candidate failed for","Add the missing public key / signer to the set that actually signs the tokens","Remove rotated keys from the set if tokens should no longer verify with them, and reissue tokens","Verify each key in the set independently to isolate which one is misconfigured"],"exampleFix":"// before\nnew SignedWithOneInSet(new SignedWith(new Sha256(), $oldKey), new SignedWith(new Sha256(), $newKey));\n// after (include the key the token was actually signed with)\nnew SignedWithOneInSet(new SignedWith(new Sha256(), $oldKey), new SignedWith(new Sha256(), $newKey), new SignedWith(new Sha256(), $rotatedOutKey));","handlingStrategy":"try-catch","validationCode":"foreach ($candidates as $key) {\n    try { (new Validator())->assert($token, new SignedWith(new Sha256(), $key)); return true; } catch (ConstraintViolation) {}\n}\nreturn false;","typeGuard":"null","tryCatchPattern":"try {\n    $validator->assert($token, $signedWithOneInSet);\n} catch (ConstraintViolation $e) {\n    // $e->getMessage() lists each candidate's failure; route to key-rotation fallback\n}","preventionTips":["Keep the key set in sync with all keys that could plausibly have signed live tokens","Drop truly revoked keys and force reissue rather than leaving tokens unverifiable","Log the per-constraint messages to diagnose which key candidate mismatched"],"tags":["jwt","signature","key-rotation","validation"],"backgroundTag":"jwt-signature-verification-failed","analyzedSha":"375813049c24c7111bda8b6884c57b071ceb2fe7","analyzedAt":"2026-09-14T11:12:28.004Z","contentChangedAt":"2026-09-14T11:12:28.004Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}