{"record":{"id":"8931390ce17a2406","repo":"spring-projects/spring-security","slug":"an-error-occurred-reading-the-oauth-2-0-error-e","errorCode":null,"errorMessage":"An error occurred reading the OAuth 2.0 Error: ${ex.getMessage()}","messagePattern":"An error occurred reading the OAuth 2\\.0 Error: (.+?)","errorType":"http","errorClass":"HttpMessageNotReadableException","httpStatus":400,"severity":"error","filePath":"oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/http/converter/OAuth2ErrorHttpMessageConverter.java","lineNumber":87,"sourceCode":"\tprotected boolean supports(Class<?> clazz) {\n\t\treturn OAuth2Error.class.isAssignableFrom(clazz);\n\t}\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\tprotected OAuth2Error readInternal(Class<? extends OAuth2Error> clazz, HttpInputMessage inputMessage)\n\t\t\tthrows HttpMessageNotReadableException {\n\t\ttry {\n\t\t\t// gh-8157: Parse parameter values as Object in order to handle potential JSON\n\t\t\t// Object and then convert values to String\n\t\t\tMap<String, Object> errorParameters = (Map<String, Object>) this.jsonMessageConverter\n\t\t\t\t.read(STRING_OBJECT_MAP.getType(), null, inputMessage);\n\t\t\treturn this.errorConverter.convert(errorParameters.entrySet()\n\t\t\t\t.stream()\n\t\t\t\t.collect(Collectors.toMap(Map.Entry::getKey, (entry) -> String.valueOf(entry.getValue()))));\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthrow new HttpMessageNotReadableException(\n\t\t\t\t\t\"An error occurred reading the OAuth 2.0 Error: \" + ex.getMessage(), ex, inputMessage);\n\t\t}\n\t}\n\n\t@Override\n\tprotected void writeInternal(OAuth2Error oauth2Error, HttpOutputMessage outputMessage)\n\t\t\tthrows HttpMessageNotWritableException {\n\t\ttry {\n\t\t\tMap<String, String> errorParameters = this.errorParametersConverter.convert(oauth2Error);\n\t\t\tthis.jsonMessageConverter.write(errorParameters, STRING_OBJECT_MAP.getType(), MediaType.APPLICATION_JSON,\n\t\t\t\t\toutputMessage);\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthrow new HttpMessageNotWritableException(\n\t\t\t\t\t\"An error occurred writing the OAuth 2.0 Error: \" + ex.getMessage(), ex);\n\t\t}\n\t}\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-core/src/main/java/org/springframework/security/oauth2/core/http/converter/OAuth2ErrorHttpMessageConverter.java#L69-L105","documentation":"This HttpMessageNotReadableException is thrown by OAuth2ErrorHttpMessageConverter.readInternal when the incoming JSON error payload cannot be read or converted into an OAuth2Error. It wraps failures from the JSON converter or from converting the parameter map into a Map<String,String> of error parameters (error, error_description, error_uri).","triggerScenarios":"Calling readInternal/read on an OAuth2ErrorHttpMessageConverter when the body is not valid JSON, not an object, or the stream read throws (connection closed mid-body).","commonSituations":"The token/revocation endpoint returns a non-JSON error page (proxy, wrong endpoint), or the response body is empty/garbage when handling an OAuth error response.","solutions":["Inspect ex.getCause() to see the underlying parse/conversion failure.","Confirm the failing endpoint returns an RFC 6749 error JSON object like {\"error\":\"invalid_grant\"}.","Check the request reached the correct OAuth endpoint (not an HTML login page or 404).","Ensure a JSON message converter (Jackson) is configured on the converter.","Handle it by wrapping into OAuth2AuthorizationException downstream instead of failing hard."],"exampleFix":"// before\nOAuth2Error error = converter.read(OAuth2Error.class, inputMessage);\n// after\ntry {\n    OAuth2Error error = converter.read(OAuth2Error.class, inputMessage);\n} catch (HttpMessageNotReadableException ex) {\n    logger.warn(\"OAuth2 error response not readable\", ex.getCause());\n}","handlingStrategy":"try-catch","validationCode":"if (body == null || !body.strip().startsWith(\"{\")) {\n    throw new IllegalArgumentException(\"Expected a JSON error object body\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    OAuth2Error error = converter.read(OAuth2Error.class, inputMessage);\n} catch (HttpMessageNotReadableException ex) {\n    logger.warn(\"OAuth2 error body unreadable\", ex.getCause());\n    return new OAuth2Error(\"server_error\", \"Malformed error response\", null);\n}","preventionTips":["Verify the endpoint responds with RFC 6749 error JSON on failure.","Guard against proxies rewriting error bodies into HTML.","Add integration tests that exercise error responses from the token endpoint."],"tags":["oauth2","http-message-conversion","json","spring-security"],"backgroundTag":"invalid-json-response","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"}