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

  1. Use Spring Security's supported customization points (withJwkSetUri, withPublicKey, withSecretKey, setJwsAlgorithms) instead of a custom JWSKeySelector
  2. If a custom selector is required, extend or wrap JWSVerificationKeySelector so the instanceof check passes
  3. 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

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


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/d44b0a42c5f51e22. Report an issue: GitHub.