spring-projects/spring-security · error · IllegalArgumentException
Unsupported key selector type + jwsKeySelector.getClass()
Error message
Unsupported key selector type + jwsKeySelector.getClass()
What it means
getExpectedJwsAlgorithms (inside NimbusReactiveJwtDecoder's builder/processor wiring) only understands JWSVerificationKeySelector; when the configured JWSKeySelector is any other Nimbus type it throws IllegalArgumentException 'Unsupported key selector type <class>'. This is an internal invariant: Spring Security's decoder expects the key selector it (or you) configured to be a JWSVerificationKeySelector so it can derive the allowed JWS algorithms.
Source
Thrown at oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/NimbusReactiveJwtDecoder.java:532
.map((processor) -> Tuples.of(processor, getExpectedJwsAlgorithms(processor.getJWSKeySelector())))
.cache((processor) -> FOREVER, (ex) -> Duration.ZERO, () -> Duration.ZERO);
return (jwt) -> {
return jwtProcessorMono.flatMap((tuple) -> {
ConfigurableJWTProcessor<JWKSecurityContext> processor = tuple.getT1();
Function<JWSAlgorithm, Boolean> expectedJwsAlgorithms = tuple.getT2();
JWKSelector selector = createSelector(expectedJwsAlgorithms, jwt.getHeader());
return source.get(selector)
.onErrorMap((ex) -> new IllegalStateException("Could not obtain the keys", ex))
.map((jwkList) -> createClaimsSet(processor, jwt, new JWKSecurityContext(jwkList)));
});
};
}
private Function<JWSAlgorithm, Boolean> getExpectedJwsAlgorithms(JWSKeySelector<?> jwsKeySelector) {
if (jwsKeySelector instanceof JWSVerificationKeySelector) {
return ((JWSVerificationKeySelector<?>) jwsKeySelector)::isAllowed;
}
throw new IllegalArgumentException("Unsupported key selector type " + jwsKeySelector.getClass());
}
private JWKSelector createSelector(Function<JWSAlgorithm, Boolean> expectedJwsAlgorithms, Header header) {
JWSHeader jwsHeader = (JWSHeader) header;
if (!expectedJwsAlgorithms.apply(jwsHeader.getAlgorithm())) {
throw new BadJwtException("Unsupported algorithm of " + header.getAlgorithm());
}
return new JWKSelector(JWKMatcher.forJWSHeader(jwsHeader));
}
}
/**
* A builder for creating {@link NimbusReactiveJwtDecoder} instances based on a public
* key.
*
* @since 5.2
*/View on GitHub (pinned to 96852e8860)
Solutions
- Use Spring Security's supported customization points (withJwkSetUri, withPublicKey, withSecretKey, setJwsAlgorithms) instead of a custom JWSKeySelector
- If a custom selector is required, extend or wrap JWSVerificationKeySelector so the instanceof check passes
- Downstream of this error, only provide algorithms via setJwsAlgorithms on the builder rather than replacing the selector
Example fix
// before
processor.setJWSKeySelector(new MyCustomJWSKeySelector<>()); // throws in getExpectedJwsAlgorithms
// after
NimbusReactiveJwtDecoder decoder = NimbusReactiveJwtDecoder.withJwkSetUri(jwkSetUri)
.jwsAlgorithms(algs -> algs.addAll(List.of(SignatureAlgorithm.RS256, SignatureAlgorithm.ES256)))
.build(); Defensive patterns
Strategy: type-guard
Validate before calling
// before building, assert the selector type the decoder supports
if (!(jwsKeySelector instanceof JWSVerificationKeySelector)) {
throw new IllegalStateException("Configure algorithms via setJwsAlgorithms, not a custom JWSKeySelector");
} Type guard
static boolean isSupportedKeySelector(JWSKeySelector<?> sel) {
return sel instanceof JWSVerificationKeySelector;
} Try / catch
try {
NimbusReactiveJwtDecoder decoder = builder.build();
} catch (IllegalArgumentException ex) {
if (ex.getMessage().startsWith("Unsupported key selector type")) {
throw new ConfigurationException("Use builder.setJwsAlgorithms instead of a custom JWSKeySelector");
}
throw ex;
} Prevention
- Configure allowed algorithms via the builder's setJwsAlgorithms, never by replacing the Nimbus JWSKeySelector
- If Nimbus customization is unavoidable, extend JWSVerificationKeySelector rather than implementing JWSKeySelector from scratch
- Pin Nimbus JOSE+JWT versions compatible with your Spring Security version
- Write a startup smoke test that decodes a sample token to surface configuration errors early
When it happens
Trigger: Building the decoder so that the underlying ConfigurableJWTProcessor's JWSKeySelector is not a JWSVerificationKeySelector — e.g. passing a custom JWSKeySelector (JWEDecryptionKeySelector, implicit/ federated selectors, or a custom implementation) into the Nimbus configuration used by jwtProcessorMono, then the decoder tries to compute expected algorithms for JWK selection.
Common situations: Customizing Nimbus internals by supplying a bespoke JWSKeySelector; library/version change where Nimbus returns a wrapped selector type; copying configuration code that sets a key selector Spring Security does not recognize.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot apply {configurer} to already built object
- managerPassword is required if managerDn is supplied
- org.springframework.security.config.annotation.method.config
- The Filter class {registeredFilter.getName()} does not have
- The Filter class {filter.getClass().getName()} does not have
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/d44b0a42c5f51e22.
Report an issue: GitHub.