spring-projects/spring-security · error · OAuth2AuthorizationCodeRequestAuthenticationException

OAuth 2.0 Parameter: ${parameterName}

Error message

OAuth 2.0 Parameter: ${parameterName}

What it means

OAuth2AuthorizationCodeRequestAuthenticationConverter throws OAuth2AuthorizationCodeRequestAuthenticationException with the description "OAuth 2.0 Parameter: <parameterName>" when the authorization endpoint request (/oauth2/authorize) is missing or has an invalid required parameter (e.g. response_type, client_id, redirect_uri, scope, state, code_challenge). The library rejects malformed authorization requests early in the converter so they never reach the authorization service. The description names the offending parameter so the client can fix the request.

Source

Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/OAuth2AuthorizationCodeRequestAuthenticationConverter.java:240

			.toString()
			.toLowerCase(Locale.ROOT)
			.endsWith(authorizationServerSettings.getPushedAuthorizationRequestEndpoint().toLowerCase(Locale.ROOT));
	}

	private static RequestMatcher createDefaultRequestMatcher() {
		final RequestMatcher authorizationConsentMatcher = OAuth2AuthorizationConsentAuthenticationConverter
			.createDefaultRequestMatcher();
		return (request) -> "GET".equals(request.getMethod())
				|| ("POST".equals(request.getMethod()) && !authorizationConsentMatcher.matches(request));
	}

	private static void throwError(String errorCode, String parameterName) {
		throwError(errorCode, parameterName, DEFAULT_ERROR_URI);
	}

	private static void throwError(String errorCode, String parameterName, String errorUri) {
		OAuth2Error error = new OAuth2Error(errorCode, "OAuth 2.0 Parameter: " + parameterName, errorUri);
		throw new OAuth2AuthorizationCodeRequestAuthenticationException(error, null);
	}

}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Inspect the exception's OAuth2Error description to identify the exact parameter named after "OAuth 2.0 Parameter:" and ensure it is sent correctly.
  2. Fix the authorization request URL to include all required params: response_type=code, client_id, redirect_uri (registered), and scope if required.
  3. If PKCE is enforced, send a valid code_challenge (S256) and code_challenge_method with the authorization request.
  4. If you must customize handling, register a custom AuthenticationConverter or FailureHandler on the authorization server filter instead of bypassing validation.

Example fix

// before: hand-built authorize URL missing params
String url = "/oauth2/authorize?client_id=my-client";
// after
String url = "/oauth2/authorize?response_type=code"
    + "&client_id=my-client"
    + "&redirect_uri=https://app.example.com/callback"
    + "&scope=openid"
    + "&state=" + state
    + "&code_challenge=" + s256Challenge + "&code_challenge_method=S256";
Defensive patterns

Strategy: validation

Validate before calling

function validateAuthorizeRequest(params) {
  const errors = [];
  if (!params.get('response_type')) errors.push('response_type is required');
  else if (params.get('response_type') !== 'code') errors.push('response_type must be "code"');
  if (!params.get('client_id')) errors.push('client_id is required');
  if (!params.get('redirect_uri')) errors.push('redirect_uri is required');
  else { try { new URL(params.get('redirect_uri')); } catch { errors.push('redirect_uri must be an absolute URL'); } }
  return errors;
}
const errs = validateAuthorizeRequest(new URLSearchParams(authorizeUrl));
if (errs.length) throw new Error('Invalid authorize request: ' + errs.join('; '));

Type guard

function hasRequiredAuthorizeParams(p) {
  return typeof p === 'object' && p !== null
    && typeof p.client_id === 'string' && p.client_id.length > 0
    && p.response_type === 'code'
    && typeof p.redirect_uri === 'string' && p.redirect_uri.startsWith('https://');
}

Try / catch

try {
  authorizationResponse = performAuthorizationRequest(request);
} catch (OAuth2AuthorizationCodeRequestAuthenticationException e) {
  OAuth2Error err = e.getError();
  logger.warn("Authorization request rejected: code={} description={}", err.getErrorCode(), err.getDescription());
  // redirect user back to client with error=invalid_request&error_description=...
}

Prevention

When it happens

Trigger: convert() calls throwError() when: the request URI is not the configured authorization endpoint; required parameters like client_id or response_type are absent; response_type is not "code"; redirect_uri is malformed or missing; scope contains invalid characters; or PKCE code_challenge/code_challenge_method values are invalid on an authorization code request.

Common situations: A client app builds the /oauth2/authorize URL by hand and forgets response_type=code; a misconfigured redirect_uri (not registered or not an absolute URL); missing state parameter when the client requires it; typos in scope strings; an upgraded Spring Authorization Server version enforcing stricter parameter validation than the client sends.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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