{"record":{"id":"b1fd21a098ff05bd","repo":"spring-projects/spring-security","slug":"an-error-occurred-reading-the-userinfo-response","errorCode":null,"errorMessage":"An error occurred reading the UserInfo response: ${ex.getMessage()}","messagePattern":"An error occurred reading the UserInfo response: (.+?)","errorType":"http","errorClass":"HttpMessageNotReadableException","httpStatus":400,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/http/converter/OidcUserInfoHttpMessageConverter.java","lineNumber":83,"sourceCode":"\t\tthis.jsonMessageConverter = converter;\n\t}\n\n\t@Override\n\tprotected boolean supports(Class<?> clazz) {\n\t\treturn OidcUserInfo.class.isAssignableFrom(clazz);\n\t}\n\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\tprotected OidcUserInfo readInternal(Class<? extends OidcUserInfo> clazz, HttpInputMessage inputMessage)\n\t\t\tthrows HttpMessageNotReadableException {\n\t\ttry {\n\t\t\tMap<String, Object> userInfoParameters = (Map<String, Object>) this.jsonMessageConverter\n\t\t\t\t.read(STRING_OBJECT_MAP.getType(), null, inputMessage);\n\t\t\treturn this.userInfoConverter.convert(userInfoParameters);\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 UserInfo response: \" + ex.getMessage(), ex, inputMessage);\n\t\t}\n\t}\n\n\t@Override\n\tprotected void writeInternal(OidcUserInfo oidcUserInfo, HttpOutputMessage outputMessage)\n\t\t\tthrows HttpMessageNotWritableException {\n\t\ttry {\n\t\t\tMap<String, Object> userInfoResponseParameters = this.userInfoParametersConverter.convert(oidcUserInfo);\n\t\t\tthis.jsonMessageConverter.write(userInfoResponseParameters, STRING_OBJECT_MAP.getType(),\n\t\t\t\t\tMediaType.APPLICATION_JSON, outputMessage);\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 UserInfo response: \" + ex.getMessage(), ex);\n\t\t}\n\t}\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/oidc/http/converter/OidcUserInfoHttpMessageConverter.java#L65-L101","documentation":"This HttpMessageNotReadableException is thrown by OidcUserInfoHttpMessageConverter.readInternal when reading the UserInfo response fails. Either the JSON body cannot be parsed into a Map by the jsonMessageConverter, or the resulting parameters fail the OidcUserInfoConverter validation. The underlying exception message is appended for diagnosis.","triggerScenarios":"Calling OidcUserService/UserInfo endpoint processing where the UserInfo endpoint returns malformed JSON, an error payload, or parameters that fail OidcUserInfoConverter validation (e.g. missing 'sub' claim).","commonSituations":"Upstream UserInfo endpoint returns HTML error pages, empty bodies, or non-standard claims; network proxies intercept the response; OIDC provider returns an error response with 200-shaped parsing expectations.","solutions":["Inspect the wrapped cause message to see whether it was JSON parsing or UserInfo validation","Verify the UserInfo endpoint actually returns application/json with a valid JSON object","Ensure the response includes the required 'sub' claim per the OIDC spec","Log/capture the raw response body to confirm what the server returned"],"exampleFix":"// before: assuming UserInfo always succeeds\nOidcUserInfo userInfo = restTemplate.getForObject(...);\n// after: guard against bad responses\nif (!response.getHeaders().getContentType().isCompatibleWith(MediaType.APPLICATION_JSON)) {\n    throw new IllegalStateException(\"UserInfo endpoint returned non-JSON: \" + response.getBody());\n}","handlingStrategy":"validation","validationCode":"// Before relying on UserInfo, verify the response is a JSON object with 'sub'\nif (body == null || !body.startsWith(\"{\")) throw new IllegalStateException(\"UserInfo not JSON\");\nif (!body.contains(\"\\\"sub\\\"\")) throw new IllegalStateException(\"UserInfo missing sub claim\");","typeGuard":"boolean isValidUserInfoResponse(Map<String,Object> params) {\n    return params != null && params.get(\"sub\") instanceof String s && !s.isEmpty();\n}","tryCatchPattern":"try {\n    OidcUser user = oidcUserService.loadUser(userRequest);\n} catch (OAuth2AuthenticationException | InvalidBearerTokenException e) {\n    // inspect cause for 'An error occurred reading the UserInfo response'\n    logger.error(\"UserInfo read failed: {}\", e.getCause());\n}","preventionTips":["Confirm the OIDC provider's userinfo_endpoint returns application/json","Test the UserInfo endpoint directly with the access token (curl) before integration","Validate required claims (sub) against the OIDC spec"],"tags":["http","json","openid-connect","userinfo"],"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"}