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
- Inspect the exception's OAuth2Error description to identify the exact parameter named after "OAuth 2.0 Parameter:" and ensure it is sent correctly.
- Fix the authorization request URL to include all required params: response_type=code, client_id, redirect_uri (registered), and scope if required.
- If PKCE is enforced, send a valid code_challenge (S256) and code_challenge_method with the authorization request.
- 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
- Use a maintained OAuth2 client library to build the authorize URL instead of string concatenation.
- Keep redirect_uri values identical to those registered on the server (scheme, host, port, path).
- Always send response_type=code, client_id, redirect_uri, scope, and state in every authorization request.
- Generate a proper S256 code_challenge when PKCE is enforced.
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
- OAuth 2.0 Parameter: ${parameterName}
- OAuth2Error from upstream authorization exception (dynamic)
- Unable to create an {OAuth2AuthorizedClientManager} bean. Ex
- invalid_dpop_proof
- invalid_scope
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/d4bc080659b5ffab.
Report an issue: GitHub.