{"record":{"id":"b0effa3caa77977c","repo":"spring-projects/spring-security","slug":"invalid-token-response","errorCode":"invalid_token_response","errorMessage":"Empty OAuth 2.0 Access Token Response","messagePattern":"Empty OAuth 2\\.0 Access Token Response","errorType":"error_code","errorClass":"OAuth2AuthorizationException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/AbstractRestClientOAuth2AccessTokenResponseClient.java","lineNumber":98,"sourceCode":"\tprivate Consumer<MultiValueMap<String, String>> parametersCustomizer = (parameters) -> {\n\t};\n\n\tAbstractRestClientOAuth2AccessTokenResponseClient() {\n\t}\n\n\t@Override\n\tpublic OAuth2AccessTokenResponse getTokenResponse(T grantRequest) {\n\t\tAssert.notNull(grantRequest, \"grantRequest cannot be null\");\n\t\ttry {\n\t\t\t// @formatter:off\n\t\t\tOAuth2AccessTokenResponse accessTokenResponse = this.requestEntityConverter.convert(grantRequest)\n\t\t\t\t\t.retrieve()\n\t\t\t\t\t.body(OAuth2AccessTokenResponse.class);\n\t\t\t// @formatter:on\n\t\t\tif (accessTokenResponse == null) {\n\t\t\t\tOAuth2Error error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE,\n\t\t\t\t\t\t\"Empty OAuth 2.0 Access Token Response\", null);\n\t\t\t\tthrow new OAuth2AuthorizationException(error);\n\t\t\t}\n\t\t\treturn accessTokenResponse;\n\t\t}\n\t\tcatch (RestClientException ex) {\n\t\t\tOAuth2Error error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE,\n\t\t\t\t\t\"An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: \"\n\t\t\t\t\t\t\t+ ex.getMessage(),\n\t\t\t\t\tnull);\n\t\t\tthrow new OAuth2AuthorizationException(error, ex);\n\t\t}\n\t}\n\n\tprivate RequestHeadersSpec<?> validatingPopulateRequest(T grantRequest) {\n\t\tvalidateClientAuthenticationMethod(grantRequest);\n\t\treturn populateRequest(grantRequest);\n\t}\n\n\tprivate void validateClientAuthenticationMethod(T grantRequest) {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/endpoint/AbstractRestClientOAuth2AccessTokenResponseClient.java#L80-L116","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n.registration.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)\n  .tokenUri(\"https://auth.example.com/api\")\n// after\n.registration.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)\n  .tokenUri(\"https://auth.example.com/oauth2/token\")","handlingStrategy":"validation","validationCode":"// before login, sanity-check the token endpoint\nHttpHeaders h = new HttpHeaders();\nResponseEntity<String> probe = rest.exchange(tokenUri, HttpMethod.POST, new HttpEntity<>(h), String.class);\nif (!probe.getHeaders().getContentType().isCompatibleWith(MediaType.APPLICATION_JSON)) {\n    throw new IllegalStateException(\"tokenUri does not return JSON: \" + probe.getHeaders().getContentType());\n}","typeGuard":null,"tryCatchPattern":"catch (OAuth2AuthenticationException | OAuth2AuthorizationException ex) { if (\"invalid_token_response\".equals(ex.getError().getErrorCode())) { log.error(\"Token endpoint returned empty body; check tokenUri/proxies\"); } throw ex; }","preventionTips":["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."],"tags":["oauth2","http","token-endpoint","empty-response","spring-security"],"backgroundTag":"empty-response-body","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}