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

  1. Verify the client_id in the authorization request matches a RegisteredClient in your RegisteredClientRepository
  2. Register the client (createRegisteredClient / repository entry) before initiating the flow
  3. Check the authorize URL is constructed with the correct client_id parameter
  4. 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

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


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/9cf81c667567bb40. Report an issue: GitHub.