{"record":{"id":"c5bce7305292c220","repo":"apereo/cas","slug":"unable-to-verify-jwt-assertion-with-any-of-the-con","errorCode":null,"errorMessage":"Unable to verify JWT assertion with any of the configured JSON web keys","messagePattern":"Unable to verify JWT assertion with any of the configured JSON web keys","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-heimdall/src/main/java/org/apereo/cas/heimdall/engine/DefaultAuthorizationPrincipalParser.java","lineNumber":227,"sourceCode":"            .filter(PublicJsonWebKey.class::isInstance)\n            .filter(key -> key.getKey() != null)\n            .map(PublicJsonWebKey.class::cast)\n            .toList();\n    }\n\n    protected String verifyAssertion(final String assertion, final List<PublicJsonWebKey> jsonWebKeys) {\n        for (val jsonWebKey : jsonWebKeys) {\n            try {\n                val verified = EncodingUtils.verifyJwsSignature(jsonWebKey.getPublicKey(), assertion);\n                val verifiedAssertion = new String(verified, StandardCharsets.UTF_8);\n                LOGGER.trace(\"Successfully verified JWT assertion with key id [{}]\", jsonWebKey.getKeyId());\n                return verifiedAssertion;\n            } catch (final Exception e) {\n                LOGGER.debug(\"Failed to verify JWT assertion via key id [{}]: [{}]. Moving on to the next key\",\n                    jsonWebKey.getKeyId(), e.getMessage());\n            }\n        }\n        throw new IllegalArgumentException(\"Unable to verify JWT assertion with any of the configured JSON web keys\");\n    }\n}\n","sourceCodeStart":209,"sourceCodeEnd":230,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-heimdall/src/main/java/org/apereo/cas/heimdall/engine/DefaultAuthorizationPrincipalParser.java#L209-L230","documentation":"verifyAssertion tries to verify the signed JWT assertion against each configured JSON web key (JWK). Each failure is logged at debug and skipped; if no key verifies the signature, it throws IllegalArgumentException 'Unable to verify JWT assertion with any of the configured JSON web keys'.","triggerScenarios":"verifiedAssertion -> verifyAssertion called with a JWT whose signature does not validate under any key in the Heimdall/JWKS keystore (wrong kid, wrong key set, or tampered token).","commonSituations":"JWKS rotation left the server without the new key; assertion signed by a different issuer key than the one registered; kid missing from the keystore config; assertion modified in transit; wrong algorithm (HS vs RS) configured.","solutions":["Verify the JWKS/keystore configured for the parser contains the public key matching the assertion's kid","Refresh/re-import the issuer's JWKS (keys may have rotated)","Confirm the assertion is signed with the expected algorithm and by the registered issuer/client","Enable debug logging for org.apereo.cas.heimdall to see the per-key failure reasons"],"exampleFix":"// before: keystore missing rotated key\n// after: reload JWKS from issuer endpoint / update registered key material\ncas.authn.heimdall... update jwt keystore to current issuer JWKS","handlingStrategy":"validation","validationCode":"// ensure the assertion kid exists in the configured keystore before verification\nString kid = signedJWT.getHeader().getKeyID();\nboolean keyKnown = jwks.getKeys().stream().anyMatch(k -> kid.equals(k.getKeyID()));","typeGuard":null,"tryCatchPattern":"try {\n    return parser.claims(token);\n} catch (IllegalArgumentException e) {\n    // refresh JWKS from issuer then retry once; else reject 401\n}","preventionTips":["Automate JWKS refresh to track issuer key rotation","Ensure assertions always carry a kid matching a registered key","Log per-key verification failures at debug to diagnose mismatches"],"tags":["jwt","signature-verification","jwks","heimdall"],"backgroundTag":"jwt-signature-verification-failed","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}