{"record":{"id":"6d9f238bc460f649","repo":"spring-projects/spring-security","slug":"failed-to-validate-the-token","errorCode":null,"errorMessage":"Failed to validate the token","messagePattern":"Failed to validate the token","errorType":"exception","errorClass":"BadJwtException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusReactiveJwtDecoder.java","lineNumber":302,"sourceCode":"\n\t/**\n\t * Use the given {@link Function} to validate JWTs.\n\t * @param source the {@link Function}\n\t * @return a {@link JwkSourceReactiveJwtDecoderBuilder} for further configurations\n\t *\n\t * @since 5.2\n\t */\n\tpublic static JwkSourceReactiveJwtDecoderBuilder withJwkSource(Function<SignedJWT, Flux<JWK>> source) {\n\t\treturn new JwkSourceReactiveJwtDecoderBuilder(source);\n\t}\n\n\tprivate static <C extends SecurityContext> JWTClaimsSet createClaimsSet(JWTProcessor<C> jwtProcessor,\n\t\t\tJWT parsedToken, @Nullable C context) {\n\t\ttry {\n\t\t\treturn jwtProcessor.process(parsedToken, context);\n\t\t}\n\t\tcatch (BadJOSEException ex) {\n\t\t\tthrow new BadJwtException(\"Failed to validate the token\", ex);\n\t\t}\n\t\tcatch (JOSEException ex) {\n\t\t\tthrow new JwtException(\"Failed to validate the token\", ex);\n\t\t}\n\t}\n\n\t/**\n\t * A builder for creating {@link NimbusReactiveJwtDecoder} instances based on a\n\t * <a target=\"_blank\" href=\"https://tools.ietf.org/html/rfc7517#section-5\">JWK Set</a>\n\t * uri.\n\t *\n\t * @since 5.2\n\t */\n\tpublic static final class JwkSetUriReactiveJwtDecoderBuilder {\n\n\t\tprivate static final JOSEObjectTypeVerifier<JWKSecurityContext> JWT_TYPE_VERIFIER = new DefaultJOSEObjectTypeVerifier<>(\n\t\t\t\tJOSEObjectType.JWT, null);\n","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusReactiveJwtDecoder.java#L284-L320","documentation":"createClaimsSet maps a BadJOSEException from the Nimbus JOSE+JWT processor to Spring Security's BadJwtException with message 'Failed to validate the token'. BadJOSEException indicates Nimbus rejected the token during processing: signature verification failed, the JWS algorithm is not in the allowed set, or a critical claim check failed.","triggerScenarios":"jwtProcessor.process(parsedToken, context) throws BadJOSEException: signature verification against the configured JWK Set/SecretKey fails, the token's alg is not in the processor's expected JWS algorithm set (e.g. 'Unsupported algorithm' / 'Algorithm not allowed'), or the JWT is rejected by Nimbus's validation hooks.","commonSituations":"Resource server and authorization server key mismatch (wrong jwk-set-uri or realm); token signed with an algorithm excluded via setJwsAlgorithms (e.g. ES384 token on an RS256-only decoder); token tampered in transit; testing with a token from a dev issuer while configured for prod.","solutions":["Confirm jwk-set-uri/issuer-uri matches the authorization server that signed the token and that the JWK Set is reachable","Check the token's alg header against decoder.setJwsAlgorithms(...); add the algorithm if it is legitimate for your deployment","Regenerate/re-obtain the access token; ensure it is not truncated, re-signed, or tampered","If using symmetric signing, verify the SecretKey/OctetSequenceKey matches the one the server used"],"exampleFix":"// before\nNimbusReactiveJwtDecoder decoder = NimbusReactiveJwtDecoder.withJwkSetUri(jwkSetUri)\n    .jwsAlgorithm(RS256::equals).build();\n// after: accept the ES384 tokens your IdP issues\nNimbusReactiveJwtDecoder decoder = NimbusReactiveJwtDecoder.withJwkSetUri(jwkSetUri)\n    .jwsAlgorithms(algs -> { algs.add(SignatureAlgorithm.RS256); algs.add(SignatureAlgorithm.ES384); })\n    .build();","handlingStrategy":"try-catch","validationCode":"// pre-check the token's alg against the algorithms the decoder allows\nString headerB64 = token.split(\"\\\\.\")[0];\nString alg = new String(Base64.getUrlDecoder().decode(headerB64));\nboolean algAllowed = alg.contains(\"\\\"RS256\\\"\");","typeGuard":"static boolean decoderSupportsAlgorithm(JWSHeader header, Set<JWSAlgorithm> allowed) {\n  return header != null && allowed.contains(header.getAlgorithm());\n}","tryCatchPattern":"try {\n  Jwt jwt = decoder.decode(token).block();\n} catch (BadJwtException ex) {\n  if (ex.getCause() instanceof BadJOSEException) {\n    log.debug(\"Signature/algorithm rejection: {}\", ex.getCause().getMessage());\n  }\n  throw new UnauthorizedException(\"invalid_token\");\n}","preventionTips":["Match the decoder's JWS algorithm set to what your IdP actually signs with","Verify jwk-set-uri serves the current signing keys for the realm","Regenerate tokens from the correct environment (dev vs prod issuer)","Guard against token tampering by transmitting over TLS only"],"tags":["jwt","signature-validation","oauth2","nimbus"],"backgroundTag":"jwt-signature-validation-failed","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}