spring-projects/spring-security · error · InvalidClientRegistrationIdException
Invalid Client Registration with Id: ${registrationId}
Error message
Invalid Client Registration with Id: ${registrationId} What it means
DefaultOAuth2AuthorizationRequestResolver.resolve looks up the ClientRegistration by the registrationId extracted from the request (e.g. /oauth2/authorization/{registrationId}) in the clientRegistrationRepository. When no registration exists for that id it throws InvalidClientRegistrationIdException with 'Invalid Client Registration with Id: <id>'. The library throws this to prevent building an authorization request against an unknown client registration.
Source
Thrown at oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizationRequestResolver.java:170
this.authorizationRequestCustomizer = authorizationRequestCustomizer;
}
private String getAction(HttpServletRequest request, String defaultAction) {
String action = request.getParameter("action");
if (action == null) {
return defaultAction;
}
return action;
}
private @Nullable OAuth2AuthorizationRequest resolve(HttpServletRequest request, String registrationId,
String redirectUriAction) {
if (registrationId == null) {
return null;
}
ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(registrationId);
if (clientRegistration == null) {
throw new InvalidClientRegistrationIdException("Invalid Client Registration with Id: " + registrationId);
}
OAuth2AuthorizationRequest.Builder builder = getBuilder(clientRegistration);
String redirectUriStr = expandRedirectUri(request, clientRegistration, redirectUriAction);
String authorizationUri = clientRegistration.getProviderDetails().getAuthorizationUri();
Assert.hasText(authorizationUri, "Authorization URI is required");
// @formatter:off
builder.clientId(clientRegistration.getClientId())
.authorizationUri(authorizationUri)
.redirectUri(redirectUriStr)
.scopes(clientRegistration.getScopes())
.state(DEFAULT_STATE_GENERATOR.generateKey());
// @formatter:on
this.authorizationRequestCustomizer.accept(builder);
return builder.build();View on GitHub (pinned to 96852e8860)
Solutions
- Compare the id in the failing URL with spring.security.oauth2.client.registration.* keys (or the registrations registered in the ClientRegistrationRepository) and fix the mismatch.
- Log/inspect registrationId at the resolver or add a custom OAuth2AuthorizationRequestResolver to validate ids against your tenant store before delegating.
- If registrations are dynamic/multi-tenant, implement a ClientRegistrationRepository (e.g. JdbcClientRegistrationRepository or custom findByRegistrationId) that resolves tenant ids at runtime.
- Return a friendly 404/redirect for unknown registration ids by catching InvalidClientRegistrationIdException in an AuthenticationFailureHandler or error controller instead of an unhandled 500.
Example fix
// before <a href="/oauth2/authorization/google">Login</a> // config: spring.security.oauth2.client.registration.google-idp.client-id=... // after <a href="/oauth2/authorization/google-idp">Login</a> // registrationId in URL must exactly match a configured registration
Defensive patterns
Strategy: validation
Validate before calling
String registrationId = "google-idp";
ClientRegistration reg = clientRegistrationRepository.findByRegistrationId(registrationId);
if (reg == null) {
throw new IllegalStateException("No ClientRegistration for id " + registrationId
+ "; configured ids must match links like /oauth2/authorization/<id>");
} Try / catch
try {
OAuth2AuthorizationRequest req = resolver.resolve(request);
} catch (InvalidClientRegistrationIdException ex) {
// log the attempted id and redirect the user to a friendly error page (404)
response.sendRedirect("/login?error=unknown_provider");
} Prevention
- Generate login links from configured registration ids, never hardcode them
- Validate all login links in templates against current registration config in tests
- Keep registration ids stable when refactoring provider config
- For multi-tenant apps, resolve ids dynamically via a custom ClientRegistrationRepository
When it happens
Trigger: A request hits /oauth2/authorization/{id} or /login/oauth2/code/{id} with a registrationId that has no matching entry in the configured ClientRegistrationRepository (InMemoryClientRegistrationRepository or discovery-based repository).
Common situations: Typo in the login link's registration id (e.g. /oauth2/authorization/google vs configured 'google-idp'); registration removed/renamed in config while cached pages still link to the old id; multi-tenant dynamic registration not returning the requested id; case mismatch in the id.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- No enum constant org.springframework.security.oauth2.client.
- missing_user_info_uri
- missing_user_name_attribute
- 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/f1e1bb163b179ae7.
Report an issue: GitHub.