spring-projects/spring-security · error · OAuth2AuthorizationException
invalid_algorithm
invalid_algorithm
Error message
Unable to resolve JWS (signing) algorithm from JWK associated to client registration '${registrationId}'. What it means
After a JWK is resolved, the converter maps it to a JWS signing algorithm (e.g., RSA->RS256, EC->ES256). If resolveAlgorithm(jwk) returns null, the JWK's key type/algorithm is not supported for signing client assertions, so invalid_algorithm is thrown.
Source
Thrown at oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/NimbusJwtClientAuthenticationParametersConverter.java:133
return null;
}
JWK jwk = this.jwkResolver.apply(clientRegistration);
if (jwk == null) {
OAuth2Error oauth2Error = new OAuth2Error(INVALID_KEY_ERROR_CODE,
"Failed to resolve JWK signing key for client registration '"
+ clientRegistration.getRegistrationId() + "'.",
null);
throw new OAuth2AuthorizationException(oauth2Error);
}
JwsAlgorithm jwsAlgorithm = resolveAlgorithm(jwk);
if (jwsAlgorithm == null) {
OAuth2Error oauth2Error = new OAuth2Error(INVALID_ALGORITHM_ERROR_CODE,
"Unable to resolve JWS (signing) algorithm from JWK associated to client registration '"
+ clientRegistration.getRegistrationId() + "'.",
null);
throw new OAuth2AuthorizationException(oauth2Error);
}
JwsHeader.Builder headersBuilder = JwsHeader.with(jwsAlgorithm);
Instant issuedAt = Instant.now();
Instant expiresAt = issuedAt.plus(Duration.ofSeconds(60));
// @formatter:off
JwtClaimsSet.Builder claimsBuilder = JwtClaimsSet.builder()
.issuer(clientRegistration.getClientId())
.subject(clientRegistration.getClientId())
.audience(Collections.singletonList(clientRegistration.getProviderDetails().getTokenUri()))
.id(UUID.randomUUID().toString())
.issuedAt(issuedAt)
.expiresAt(expiresAt);
// @formatter:on
JwtClientAuthenticationContext<T> jwtClientAssertionContext = new JwtClientAuthenticationContext<>(View on GitHub (pinned to 96852e8860)
Solutions
- Use an RSA or EC signing key whose JWK has kty RSA/EC and use sig.
- Regenerate the key: RSA 2048+ for RS256/PS256, or P-256/384/521 EC key for ES256.
- Set the alg/kid metadata on the JWK so the algorithm can be resolved unambiguously.
- Upgrade spring-security-oauth2-client if the key uses a newer algorithm your version does not map.
Example fix
// before: symmetric key generated for HS256 via jwkResolver
OctetSequenceKey key = new OctetSequenceKey.Builder(secret).build();
// after: RSA signing key
RSAKey key = new RSAKey.Builder(rsaPublicKey).privateKey(rsaPrivateKey).keyID("client-1").build(); Defensive patterns
Strategy: validation
Validate before calling
JWK jwk = jwkResolver.apply(clientRegistration);
String kty = jwk != null ? jwk.getKeyType().getValue() : null;
if (!"RSA".equals(kty) && !"EC".equals(kty)) {
throw new IllegalStateException("Unsupported signing key type " + kty + "; use RSA or EC");
} Type guard
boolean isSupportedSigningJwk(JWK jwk) {
return jwk != null
&& (KeyType.RSA.equals(jwk.getKeyType()) || KeyType.EC.equals(jwk.getKeyType()))
&& (jwk.getKeyUse() == null || KeyUse.SIG.equals(jwk.getKeyUse()));
} Try / catch
catch (OAuth2AuthorizationException ex) { if ("invalid_algorithm".equals(ex.getError().getErrorCode())) { throw new IllegalStateException("JWK key type not signable; regenerate as RSA/EC", ex); } throw ex; } Prevention
- Generate RSA-2048+ or P-256 EC keys for client JWT authentication, not symmetric secrets.
- Verify the JWK's use is sig and alg matches the AS's token_endpoint_auth_signing_alg_values_supported.
- Unit-test resolveAlgorithm(jwk) for every key you ship.
- Pin JWK kid/alg so algorithm resolution is deterministic.
When it happens
Trigger: Thrown in convert() when the resolved JWK's key type has no supported JwsAlgorithm mapping — e.g., an octet-sequence (symmetric) JWK, a JWK with an unsupported curve, or one missing the required key-use/algorithm metadata.
Common situations: Keystore exported as symmetric/HMAC key instead of RSA/EC pair, EC key with an unusual P-curve unsupported by Nimbus, JWK with "use":"enc" instead of "sig", or a too-new algorithm on an older spring-security-oauth2-client version.
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
- invalid_key
- Unsupported alg parameter in JWS Header: ${algorithm.getName
- Missing jwk parameter in JWS Header.
- Unable to create an {OAuth2AuthorizedClientManager} bean. Ex
- invalid_dpop_proof
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/3d0249e9a795b29e.
Report an issue: GitHub.