{"record":{"id":"5ef13ed77569f7df","repo":"spring-projects/spring-security","slug":"missing-signature-verifier-5ef13e","errorCode":"missing_signature_verifier","errorMessage":"Failed to find a Signature Verifier for Client Registration: '${registrationId}'. Check to ensure you have configured the JwkSet URI.","messagePattern":"Failed to find a Signature Verifier for Client Registration: '(.+?)'\\. Check to ensure you have configured the JwkSet URI\\.","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcIdTokenDecoderFactory.java","lineNumber":170,"sourceCode":"\t\t\t// the TLS server validation MAY be used to validate the issuer in place of\n\t\t\t// checking the token signature.\n\t\t\t// The Client MUST validate the signature of all other ID Tokens according to\n\t\t\t// JWS [JWS]\n\t\t\t// using the algorithm specified in the JWT alg Header Parameter.\n\t\t\t// The Client MUST use the keys provided by the Issuer.\n\t\t\t//\n\t\t\t// 7. The alg value SHOULD be the default of RS256 or the algorithm sent by\n\t\t\t// the Client\n\t\t\t// in the id_token_signed_response_alg parameter during Registration.\n\n\t\t\tString jwkSetUri = clientRegistration.getProviderDetails().getJwkSetUri();\n\t\t\tif (!StringUtils.hasText(jwkSetUri)) {\n\t\t\t\tOAuth2Error oauth2Error = new OAuth2Error(MISSING_SIGNATURE_VERIFIER_ERROR_CODE,\n\t\t\t\t\t\t\"Failed to find a Signature Verifier for Client Registration: '\"\n\t\t\t\t\t\t\t\t+ clientRegistration.getRegistrationId()\n\t\t\t\t\t\t\t\t+ \"'. Check to ensure you have configured the JwkSet URI.\",\n\t\t\t\t\t\tnull);\n\t\t\t\tthrow new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());\n\t\t\t}\n\t\t\treturn NimbusJwtDecoder.withJwkSetUri(jwkSetUri).jwsAlgorithm((SignatureAlgorithm) jwsAlgorithm).build();\n\t\t}\n\t\tif (jwsAlgorithm != null && MacAlgorithm.class.isAssignableFrom(jwsAlgorithm.getClass())) {\n\t\t\t// https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation\n\t\t\t//\n\t\t\t// 8. If the JWT alg Header Parameter uses a MAC based algorithm such as\n\t\t\t// HS256, HS384, or HS512,\n\t\t\t// the octets of the UTF-8 representation of the client_secret\n\t\t\t// corresponding to the client_id contained in the aud (audience) Claim\n\t\t\t// are used as the key to validate the signature.\n\t\t\t// For MAC based algorithms, the behavior is unspecified if the aud is\n\t\t\t// multi-valued or\n\t\t\t// if an azp value is present that is different than the aud value.\n\t\t\tString clientSecret = clientRegistration.getClientSecret();\n\t\t\tif (!StringUtils.hasText(clientSecret)) {\n\t\t\t\tOAuth2Error oauth2Error = new OAuth2Error(MISSING_SIGNATURE_VERIFIER_ERROR_CODE,\n\t\t\t\t\t\t\"Failed to find a Signature Verifier for Client Registration: '\"","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/OidcIdTokenDecoderFactory.java#L152-L188","documentation":"OidcIdTokenDecoderFactory builds a JwtDecoder for a ClientRegistration's ID Tokens. If the registration's JWS algorithm is an asymmetric signature algorithm (e.g. RS256), a JWK Set URI is required to fetch the provider's public keys. When the registration has no jwkSetUri configured, the factory throws OAuth2AuthenticationException with code 'missing_signature_verifier'.","triggerScenarios":"jwtDecoder() -> buildDecoder() for a ClientRegistration whose providerMetadata jwk_set_uri is null/empty while the configured JWS algorithm requires asymmetric verification — e.g. building an OidcIdTokenValidator or decoding an id_token for a registration created programmatically without discovery.","commonSituations":"ClientRegistration built with CommonOAuth2Provider or withRegistrationId without issuer-uri/oidc metadata, so jwkSetUri was never populated; manual ClientRegistration.withSettings(...) that forgot .jwkSetUri(...); Spring Boot property spring.security.oauth2.client.registration.* missing provider OIDC config.","solutions":["Configure the OIDC provider via issuer-uri so Spring fetches the JWK Set URI from .well-known/openid-configuration automatically.","Or explicitly set the JWK Set URI: ClientRegistration.withSettings(s -> s.jwkSetUri(\"https://idp/.well-known/jwks.json\")).","In yaml, ensure spring.security.oauth2.client.provider.<id>.jwk-set-uri (or issuer-uri) is set for the registration's provider.","If the provider truly uses HMAC (HS256) for id_tokens, switch registration/clientSecret handling so the MacAlgorithm branch is taken instead.","Throw-site is OidcIdTokenDecoderFactory.buildDecoder — verify which factory instance/registration is being used."],"exampleFix":"// before\nClientRegistration registration = ClientRegistration.withRegistrationId(\"my-idp\")\n    .clientId(\"cid\").clientSecret(\"secret\")\n    .redirectUri(\"{baseUrl}/login/oauth2/code/{registrationId}\")\n    .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)\n    .tokenUri(\"https://idp/token\").build();\n// after: add the JWK Set URI\n    .scope(\"openid\")\n    .jwkSetUri(\"https://idp/.well-known/jwks.json\")\n    .clientName(\"My IdP\")\n    .build();","handlingStrategy":"validation","validationCode":"if (!StringUtils.hasText(registration.getProviderDetails()\n        .getConfigurationMetadata().get(\"jwks_uri\"))\n    && !StringUtils.hasText(registration.getProviderDetails().getJwkSetUri())) {\n    throw new IllegalStateException(\"jwkSetUri missing for \" + registration.getRegistrationId());\n}","typeGuard":null,"tryCatchPattern":"try {\n    JwtDecoder d = idTokenDecoderFactory.createDecoder(registration);\n} catch (OAuth2AuthenticationException ex) {\n    if (\"missing_signature_verifier\".equals(ex.getError().getErrorCode())) {\n        throw new IllegalStateException(\n            \"Configure jwkSetUri for registration \" + registration.getRegistrationId(), ex);\n    }\n}","preventionTips":["Prefer issuer-uri based registration so jwks_uri is auto-discovered","Add jwk-set-uri to yaml when building registrations manually","Smoke-test createDecoder() at startup for every registration","Use ClientRegistration.withSettings().jwkSetUri(...) for programmatic registrations"],"tags":["oauth2","oidc","jwt","configuration"],"backgroundTag":"missing-required-config-field","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"}