spring-projects/spring-security · error · OAuth2AuthorizationException
invalid_token_response
invalid_token_response
Error message
Empty OAuth 2.0 Access Token Response
What it means
The token endpoint returned a 2xx response whose body deserialized to null or nothing usable, so the client cannot build an OAuth2AccessTokenResponse. Spring Security throws this as invalid_token_response because an OAuth2 access token response must contain at least an access_token.
Source
Thrown at oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/AbstractRestClientOAuth2AccessTokenResponseClient.java:98
private Consumer<MultiValueMap<String, String>> parametersCustomizer = (parameters) -> {
};
AbstractRestClientOAuth2AccessTokenResponseClient() {
}
@Override
public OAuth2AccessTokenResponse getTokenResponse(T grantRequest) {
Assert.notNull(grantRequest, "grantRequest cannot be null");
try {
// @formatter:off
OAuth2AccessTokenResponse accessTokenResponse = this.requestEntityConverter.convert(grantRequest)
.retrieve()
.body(OAuth2AccessTokenResponse.class);
// @formatter:on
if (accessTokenResponse == null) {
OAuth2Error error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE,
"Empty OAuth 2.0 Access Token Response", null);
throw new OAuth2AuthorizationException(error);
}
return accessTokenResponse;
}
catch (RestClientException ex) {
OAuth2Error error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE,
"An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: "
+ ex.getMessage(),
null);
throw new OAuth2AuthorizationException(error, ex);
}
}
private RequestHeadersSpec<?> validatingPopulateRequest(T grantRequest) {
validateClientAuthenticationMethod(grantRequest);
return populateRequest(grantRequest);
}
private void validateClientAuthenticationMethod(T grantRequest) {View on GitHub (pinned to 96852e8860)
Solutions
- Verify client-registration token-uri points at the actual OAuth2 token endpoint returning application/json.
- Curl the token endpoint manually to confirm it returns a JSON body with access_token.
- Check intermediaries (proxies, gateways) that might return 200 with an empty body.
- If you control the server, fix it to return a proper token response instead of an empty 200.
Example fix
// before
.registration.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.tokenUri("https://auth.example.com/api")
// after
.registration.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.tokenUri("https://auth.example.com/oauth2/token") Defensive patterns
Strategy: validation
Validate before calling
// before login, sanity-check the token endpoint
HttpHeaders h = new HttpHeaders();
ResponseEntity<String> probe = rest.exchange(tokenUri, HttpMethod.POST, new HttpEntity<>(h), String.class);
if (!probe.getHeaders().getContentType().isCompatibleWith(MediaType.APPLICATION_JSON)) {
throw new IllegalStateException("tokenUri does not return JSON: " + probe.getHeaders().getContentType());
} Try / catch
catch (OAuth2AuthenticationException | OAuth2AuthorizationException ex) { if ("invalid_token_response".equals(ex.getError().getErrorCode())) { log.error("Token endpoint returned empty body; check tokenUri/proxies"); } throw ex; } Prevention
- Point token-uri at the documented token endpoint from the provider's .well-known/openid-configuration.
- Confirm with curl that the endpoint returns a JSON body with access_token.
- Watch for gateways that mask real errors as empty 200 responses.
- Use issuer-uri based registration so Spring resolves correct endpoints automatically.
When it happens
Trigger: Thrown in getTokenResponse() when RestClient.retrieve().body(OAuth2AccessTokenResponse.class) returns null — i.e., empty body on a successful (non-error) HTTP status from the token endpoint.
Common situations: Misconfigured token endpoint URL pointing at a health-check or HTML page that returns 200 with an empty/undecodable body; a proxy stripping the body; a custom server returning 200 with an empty payload instead of the JSON token response.
Related errors
- OAuth2Error read from WWW-Authenticate header or error respo
- method is invalid
- 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/b0effa3caa77977c.
Report an issue: GitHub.