spring-projects/spring-security · error · BadJwtException
Failed to validate the token
Error message
Failed to validate the token
What it means
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.
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
Example fix
// before
NimbusReactiveJwtDecoder decoder = NimbusReactiveJwtDecoder.withJwkSetUri(jwkSetUri)
.jwsAlgorithm(RS256::equals).build();
// after: accept the ES384 tokens your IdP issues
NimbusReactiveJwtDecoder decoder = NimbusReactiveJwtDecoder.withJwkSetUri(jwkSetUri)
.jwsAlgorithms(algs -> { algs.add(SignatureAlgorithm.RS256); algs.add(SignatureAlgorithm.ES384); })
.build(); Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check the token's alg against the algorithms the decoder allows
String headerB64 = token.split("\\.")[0];
String alg = new String(Base64.getUrlDecoder().decode(headerB64));
boolean algAllowed = alg.contains("\"RS256\""); Type guard
static boolean decoderSupportsAlgorithm(JWSHeader header, Set<JWSAlgorithm> allowed) {
return header != null && allowed.contains(header.getAlgorithm());
} Try / catch
try {
Jwt jwt = decoder.decode(token).block();
} catch (BadJwtException ex) {
if (ex.getCause() instanceof BadJOSEException) {
log.debug("Signature/algorithm rejection: {}", ex.getCause().getMessage());
}
throw new UnauthorizedException("invalid_token");
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to encode the JWT due to signing error: Failed to…
- INVALID_CLIENT
- invalid_client
- invalid_dpop_proof
- invalid_dpop_proof
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/6d9f238bc460f649.
Report an issue: GitHub.
Appendix: source
Thrown at oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusReactiveJwtDecoder.java:302
/**
* Use the given {@link Function} to validate JWTs.
* @param source the {@link Function}
* @return a {@link JwkSourceReactiveJwtDecoderBuilder} for further configurations
*
* @since 5.2
*/
public static JwkSourceReactiveJwtDecoderBuilder withJwkSource(Function<SignedJWT, Flux<JWK>> source) {
return new JwkSourceReactiveJwtDecoderBuilder(source);
}
private static <C extends SecurityContext> JWTClaimsSet createClaimsSet(JWTProcessor<C> jwtProcessor,
JWT parsedToken, @Nullable C context) {
try {
return jwtProcessor.process(parsedToken, context);
}
catch (BadJOSEException ex) {
throw new BadJwtException("Failed to validate the token", ex);
}
catch (JOSEException ex) {
throw new JwtException("Failed to validate the token", ex);
}
}
/**
* A builder for creating {@link NimbusReactiveJwtDecoder} instances based on a
* <a target="_blank" href="https://tools.ietf.org/html/rfc7517#section-5">JWK Set</a>
* uri.
*
* @since 5.2
*/
public static final class JwkSetUriReactiveJwtDecoderBuilder {
private static final JOSEObjectTypeVerifier<JWKSecurityContext> JWT_TYPE_VERIFIER = new DefaultJOSEObjectTypeVerifier<>(
JOSEObjectType.JWT, null);
View on GitHub (pinned to 96852e8860)