{"record":{"id":"3d0249e9a795b29e","repo":"spring-projects/spring-security","slug":"invalid-algorithm","errorCode":"invalid_algorithm","errorMessage":"Unable to resolve JWS (signing) algorithm from JWK associated to client registration '${registrationId}'.","messagePattern":"Unable to resolve JWS \\(signing\\) algorithm from JWK associated to client registration '(.+?)'\\.","errorType":"error_code","errorClass":"OAuth2AuthorizationException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/NimbusJwtClientAuthenticationParametersConverter.java","lineNumber":133,"sourceCode":"\t\t\treturn null;\n\t\t}\n\n\t\tJWK jwk = this.jwkResolver.apply(clientRegistration);\n\t\tif (jwk == null) {\n\t\t\tOAuth2Error oauth2Error = new OAuth2Error(INVALID_KEY_ERROR_CODE,\n\t\t\t\t\t\"Failed to resolve JWK signing key for client registration '\"\n\t\t\t\t\t\t\t+ clientRegistration.getRegistrationId() + \"'.\",\n\t\t\t\t\tnull);\n\t\t\tthrow new OAuth2AuthorizationException(oauth2Error);\n\t\t}\n\n\t\tJwsAlgorithm jwsAlgorithm = resolveAlgorithm(jwk);\n\t\tif (jwsAlgorithm == null) {\n\t\t\tOAuth2Error oauth2Error = new OAuth2Error(INVALID_ALGORITHM_ERROR_CODE,\n\t\t\t\t\t\"Unable to resolve JWS (signing) algorithm from JWK associated to client registration '\"\n\t\t\t\t\t\t\t+ clientRegistration.getRegistrationId() + \"'.\",\n\t\t\t\t\tnull);\n\t\t\tthrow new OAuth2AuthorizationException(oauth2Error);\n\t\t}\n\n\t\tJwsHeader.Builder headersBuilder = JwsHeader.with(jwsAlgorithm);\n\n\t\tInstant issuedAt = Instant.now();\n\t\tInstant expiresAt = issuedAt.plus(Duration.ofSeconds(60));\n\n\t\t// @formatter:off\n\t\tJwtClaimsSet.Builder claimsBuilder = JwtClaimsSet.builder()\n\t\t\t\t.issuer(clientRegistration.getClientId())\n\t\t\t\t.subject(clientRegistration.getClientId())\n\t\t\t\t.audience(Collections.singletonList(clientRegistration.getProviderDetails().getTokenUri()))\n\t\t\t\t.id(UUID.randomUUID().toString())\n\t\t\t\t.issuedAt(issuedAt)\n\t\t\t\t.expiresAt(expiresAt);\n\t\t// @formatter:on\n\n\t\tJwtClientAuthenticationContext<T> jwtClientAssertionContext = new JwtClientAuthenticationContext<>(","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/NimbusJwtClientAuthenticationParametersConverter.java#L115-L151","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: symmetric key generated for HS256 via jwkResolver\nOctetSequenceKey key = new OctetSequenceKey.Builder(secret).build();\n// after: RSA signing key\nRSAKey key = new RSAKey.Builder(rsaPublicKey).privateKey(rsaPrivateKey).keyID(\"client-1\").build();","handlingStrategy":"validation","validationCode":"JWK jwk = jwkResolver.apply(clientRegistration);\nString kty = jwk != null ? jwk.getKeyType().getValue() : null;\nif (!\"RSA\".equals(kty) && !\"EC\".equals(kty)) {\n    throw new IllegalStateException(\"Unsupported signing key type \" + kty + \"; use RSA or EC\");\n}","typeGuard":"boolean isSupportedSigningJwk(JWK jwk) {\n    return jwk != null\n        && (KeyType.RSA.equals(jwk.getKeyType()) || KeyType.EC.equals(jwk.getKeyType()))\n        && (jwk.getKeyUse() == null || KeyUse.SIG.equals(jwk.getKeyUse()));\n}","tryCatchPattern":"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; }","preventionTips":["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."],"tags":["oauth2","jwk","jws","jwt-signing","spring-security"],"backgroundTag":"unsupported-operation","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}