spring-projects/spring-security · error · OAuth2AuthenticationException
invalid_request
invalid_request
Error message
invalid_request
What it means
Thrown by ClientSecretBasicAuthenticationConverter.convert() when the Authorization header contains the 'Basic' scheme but is not composed of exactly two whitespace-separated parts (scheme + base64 credentials). The library treats a malformed Authorization header as an OAuth2 invalid_request per RFC 6749 section 2.3.1.
Source
Thrown at oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/ClientSecretBasicAuthenticationConverter.java:64
* @see OAuth2ClientAuthenticationToken
* @see OAuth2ClientAuthenticationFilter
*/
public final class ClientSecretBasicAuthenticationConverter implements AuthenticationConverter {
@Override
public @Nullable Authentication convert(HttpServletRequest request) {
String header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (header == null) {
return null;
}
String[] parts = header.split("\\s");
if (!parts[0].equalsIgnoreCase("Basic")) {
return null;
}
if (parts.length != 2) {
throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_REQUEST);
}
byte[] decodedCredentials;
try {
decodedCredentials = Base64.getDecoder().decode(parts[1].getBytes(StandardCharsets.UTF_8));
}
catch (IllegalArgumentException ex) {
throw new OAuth2AuthenticationException(new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST), ex);
}
String credentialsString = new String(decodedCredentials, StandardCharsets.UTF_8);
String[] credentials = credentialsString.split(":", 2);
if (credentials.length != 2 || !StringUtils.hasText(credentials[0]) || !StringUtils.hasText(credentials[1])) {
throw new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_REQUEST);
}
String clientID;
String clientSecret;View on GitHub (pinned to 96852e8860)
Solutions
- Build the Authorization header as 'Basic ' + Base64(clientId + ':' + clientSecret) with exactly one space between scheme and token.
- Verify no proxy, gateway, or client interceptor rewrites or truncates the Authorization header.
- If credentials are form-posted instead, use client_secret_post so the Basic converter is not invoked.
- Catch OAuth2AuthenticationException on the client side and log the exact outgoing header to confirm its shape.
Example fix
// before
request.setHeader("Authorization", "Basic " + clientId + ":" + secret); // missing Base64 / wrong shape
// after
String token = Base64.getEncoder().encodeToString((clientId + ":" + secret).getBytes(StandardCharsets.UTF_8));
request.setHeader("Authorization", "Basic " + token); Defensive patterns
Strategy: validation
Validate before calling
boolean validBasicHeader(String header) {
if (header == null || !header.startsWith("Basic ")) return false;
return header.split("\\s").length == 2;
} Try / catch
try { tokenResponse = client.token(request); }
catch (OAuth2AuthenticationException e) {
if ("invalid_request".equals(e.getError().getErrorCode())) { log.error("Malformed Authorization header", e); }
throw e;
} Prevention
- Always build Basic headers via a library helper rather than string concatenation.
- Assert the header matches ^Basic\s+\S+$ in client-side tests before sending.
When it happens
Trigger: Sending 'Authorization: Basic' with no credentials token, or extra tokens like 'Authorization: Basic abc extra', so parts.length != 2 after header.split("\\s").
Common situations: HTTP clients that strip the base64 credential (proxy or interceptor mangling the header); manual header construction with a missing space or trailing junk; frameworks that fold multiple header values; clients putting 'Basic' in lowercase with concatenated credentials without whitespace.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid_key
- invalid_token
- invalid_request
- invalid_token
- Unable to create an {OAuth2AuthorizedClientManager} bean. Ex
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/85e8ce54c59a6d06.
Report an issue: GitHub.