spring-projects/spring-security · error · OAuth2AuthenticationException
missing_signature_verifier
missing_signature_verifier
Error message
Failed to find a Signature Verifier for Client Registration: '${registrationId}'. Check to ensure you have configured the JwkSet URI. What it means
ReactiveOidcIdTokenDecoderFactory builds a JwtDecoder to verify the OIDC ID Token signature. When the client registration's ID Token signature algorithm is an asymmetric algorithm (e.g. RS256), the decoder needs the provider's JWK Set URI to fetch verification keys; this error is thrown when the resolved jwkSetUri is null or empty.
Source
Thrown at oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/authentication/ReactiveOidcIdTokenDecoderFactory.java:160
// and the Token Endpoint (which it is in this flow),
// the TLS server validation MAY be used to validate the issuer in place of
// checking the token signature.
// The Client MUST validate the signature of all other ID Tokens according to
// JWS [JWS]
// using the algorithm specified in the JWT alg Header Parameter.
// The Client MUST use the keys provided by the Issuer.
//
// 7. The alg value SHOULD be the default of RS256 or the algorithm sent by
// the Client
// in the id_token_signed_response_alg parameter during Registration.
String jwkSetUri = clientRegistration.getProviderDetails().getJwkSetUri();
if (!StringUtils.hasText(jwkSetUri)) {
OAuth2Error oauth2Error = new OAuth2Error(MISSING_SIGNATURE_VERIFIER_ERROR_CODE,
"Failed to find a Signature Verifier for Client Registration: '"
+ clientRegistration.getRegistrationId()
+ "'. Check to ensure you have configured the JwkSet URI.",
null);
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
}
return NimbusReactiveJwtDecoder.withJwkSetUri(jwkSetUri)
.jwsAlgorithm((SignatureAlgorithm) jwsAlgorithm)
.build();
}
if (jwsAlgorithm != null && MacAlgorithm.class.isAssignableFrom(jwsAlgorithm.getClass())) {
// https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
//
// 8. If the JWT alg Header Parameter uses a MAC based algorithm such as
// HS256, HS384, or HS512,
// the octets of the UTF-8 representation of the client_secret
// corresponding to the client_id contained in the aud (audience) Claim
// are used as the key to validate the signature.
// For MAC based algorithms, the behavior is unspecified if the aud is
// multi-valued or
// if an azp value is present that is different than the aud value.
String clientSecret = clientRegistration.getClientSecret();View on GitHub (pinned to 96852e8860)
Solutions
- Set the JWK Set URI on the registration: .jwkSetUri("https://idp/.well-known/jwks.json") or use ClientRegistrations.fromOidcIssuerLocation(issuer) which discovers it automatically.
- If the provider doesn't expose a JWKS endpoint, override the decoder factory: oidcIdTokenDecoderFactory.setJwtDecoderFactory(reg -> NimbusReactiveJwtDecoder...) with a manually supplied key.
- Confirm registration.getProviderDetails().getJwkSetUri() is non-empty before creating the decoder.
- Ensure you are not swapping in a custom ReactiveOidcIdTokenDecoderFactory that drops the jwkSetUri resolution logic.
Example fix
// before
ClientRegistration.withRegistrationId("my-idp")
.issuerUri("https://idp")
// jwkSetUri missing
.build();
// after
ClientRegistrations.fromOidcIssuerLocation("https://idp");
// or
ClientRegistration.withRegistrationId("my-idp")
.jwkSetUri("https://idp/.well-known/jwks.json")
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (!StringUtils.hasText(reg.getProviderDetails().getJwkSetUri())) {
throw new IllegalArgumentException("registration '" + reg.getRegistrationId() + "' missing jwkSetUri");
} Type guard
boolean hasJwkSetUri = r -> StringUtils.hasText(r.getProviderDetails().getJwkSetUri());
Try / catch
try { decoder = factory.create(reg); } catch (OAuth2AuthenticationException e) { if ("missing_signature_verifier".equals(e.getError().getErrorCode())) { /* fix config or fallback */ } throw e; } Prevention
- Prefer ClientRegistrations.fromOidcIssuerLocation so jwkSetUri is discovered automatically
- Assert jwkSetUri presence in a startup config test
- Keep provider metadata in one place, not scattered across overrides
When it happens
Trigger: Calling ReactiveOidcIdTokenDecoderFactory.create() (via jwtDecoder) with a ClientRegistration whose ProviderDetails has no jwkSetUri configured while the ID token signer algorithm is asymmetric (default RS256).
Common situations: Manually building a ClientRegistration (ClientRegistration.withRegistrationId...) and forgetting .jwkSetUri(...); provider metadata not loaded via ClientRegistrations.fromOidcIssuerLocation so discovery never populated jwkSetUri; custom provider-details overrides wiping the jwkSetUri.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- missing_signature_verifier
- missing_signature_verifier
- invalid_id_token
- missing_user_info_uri
- missing_user_name_attribute
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/19b88d3b9923005f.
Report an issue: GitHub.