spring-projects/spring-security · error · OAuth2AuthorizationCodeRequestAuthenticationException
invalid_request
invalid_request
Error message
OAuth 2.0 Parameter: client_id
What it means
This OAuth2AuthorizationCodeRequestAuthenticationException with invalid_request is thrown by OAuth2AuthorizationEndpointFilter's authorization code flow when the registered client cannot be resolved for the request's client_id — specifically the error description names the client_id OAuth 2.0 parameter. Per RFC 6749 section 4.1.2.1, a missing/unresolvable client_id makes the authorization request invalid.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/OAuth2AuthorizationEndpointFilter.java:491
authorizationCodeRequestAuthentication.setDetails(
OAuth2AuthorizationEndpointFilter.this.authenticationDetailsSource.buildDetails(request));
RegisteredClient registeredClient = this.registeredClientRepository
.findByClientId(authorizationCodeRequestAuthentication.getClientId());
if (registeredClient == null) {
String redirectUri = null; // Prevent redirect
OAuth2AuthorizationCodeRequestAuthenticationToken authorizationCodeRequestAuthenticationResult = new OAuth2AuthorizationCodeRequestAuthenticationToken(
authorizationCodeRequestAuthentication.getAuthorizationUri(),
authorizationCodeRequestAuthentication.getClientId(),
(Authentication) authorizationCodeRequestAuthentication.getPrincipal(), redirectUri,
authorizationCodeRequestAuthentication.getState(),
authorizationCodeRequestAuthentication.getScopes(),
authorizationCodeRequestAuthentication.getAdditionalParameters());
OAuth2Error error = new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST,
"OAuth 2.0 Parameter: " + OAuth2ParameterNames.CLIENT_ID,
"https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1");
throw new OAuth2AuthorizationCodeRequestAuthenticationException(error,
authorizationCodeRequestAuthenticationResult);
}
OAuth2AuthorizationCodeRequestAuthenticationContext authenticationContext = OAuth2AuthorizationCodeRequestAuthenticationContext
.with(authorizationCodeRequestAuthentication)
.registeredClient(registeredClient)
.build();
this.authenticationValidator.accept(authenticationContext);
ReflectionUtils.setField(this.setValidatedField, authorizationCodeRequestAuthentication, true);
// Set the validated authorization code request as a request
// attribute
// to be used upstream by OAuth2AuthorizationEndpointFilter
request.setAttribute(OAuth2AuthorizationCodeRequestAuthenticationToken.class.getName(),
authorizationCodeRequestAuthentication);
View on GitHub (pinned to 96852e8860)
Solutions
- Verify the client_id in the authorization request matches a RegisteredClient in your RegisteredClientRepository
- Register the client (createRegisteredClient / repository entry) before initiating the flow
- Check the authorize URL is constructed with the correct client_id parameter
- Ensure the RegisteredClientRepository bean points at the right store (in-memory vs JDBC)
Example fix
// before: client not registered
// GET /oauth2/authorize?response_type=code&client_id=unknown-client
// after: register the client first
RegisteredClient client = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("known-client").clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.redirectUri("https://app/cb").build();
repository.save(client); Defensive patterns
Strategy: validation
Validate before calling
// Before redirecting the user to /oauth2/authorize
boolean registered = registeredClientRepository.findByClientId(clientId) != null;
if (!registered) throw new IllegalArgumentException("Unknown client_id: " + clientId); Type guard
boolean isKnownClient(String clientId, RegisteredClientRepository repo) {
return clientId != null && !clientId.isBlank() && repo.findByClientId(clientId) != null;
} Try / catch
try {
// server-side: intercept the exception from the authorize endpoint
} catch (OAuth2AuthorizationCodeRequestAuthenticationException e) {
if ("invalid_request".equals(e.getError().getErrorCode())) {
logger.warn("Authorization request rejected for client: {}", e.getError().getDescription());
}
} Prevention
- Register all clients before issuing authorization requests
- Keep the RegisteredClientRepository store consistent across environments
- Build authorize URLs programmatically from the registered client's clientId
When it happens
Trigger: An authorization request (GET /oauth2/authorize) whose client_id has no matching RegisteredClient in the RegisteredClientRepository, or where the client_id parameter is absent/invalid at the point of context building.
Common situations: Client not registered (missing registeredClient bean or DB row); typo in client_id; authorization request built without client_id; repository lookup fails between provider checks.
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
- SERVER_ERROR
- SERVER_ERROR
- invalid_request
- OAuth 2.0 Token Introspection Parameter: ${parameterName}
- OAuth 2.0 Token Revocation Parameter: ${parameterName}
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/9cf81c667567bb40.
Report an issue: GitHub.