{"record":{"id":"6eea6c3ceff9c0b2","repo":"spring-projects/spring-security","slug":"invalid-user-info-response-6eea6c","errorCode":"invalid_user_info_response","errorMessage":"${userInfoErrorResponse.getErrorObject().getDescription()}","messagePattern":"\\$\\{userInfoErrorResponse\\.getErrorObject\\(\\)\\.getDescription\\(\\)\\}","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/userinfo/DefaultReactiveOAuth2UserService.java","lineNumber":127,"sourceCode":"\t\t\t\t\t\t\t\t+ userRequest.getClientRegistration().getRegistrationId(),\n\t\t\t\t\t\tnull);\n\t\t\t\tthrow new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());\n\t\t\t}\n\t\t\tAuthenticationMethod authenticationMethod = userRequest.getClientRegistration()\n\t\t\t\t.getProviderDetails()\n\t\t\t\t.getUserInfoEndpoint()\n\t\t\t\t.getAuthenticationMethod();\n\t\t\tWebClient.RequestHeadersSpec<?> requestHeadersSpec = getRequestHeaderSpec(userRequest, userInfoUri,\n\t\t\t\t\tauthenticationMethod);\n\t\t\t// @formatter:off\n\t\t\tMono<Map<String, Object>> userAttributes = requestHeadersSpec.retrieve()\n\t\t\t\t\t.onStatus(HttpStatusCode::isError, (response) ->\n\t\t\t\t\t\tparse(response)\n\t\t\t\t\t\t\t.map((userInfoErrorResponse) -> {\n\t\t\t\t\t\t\t\tString description = userInfoErrorResponse.getErrorObject().getDescription();\n\t\t\t\t\t\t\t\tOAuth2Error oauth2Error = new OAuth2Error(INVALID_USER_INFO_RESPONSE_ERROR_CODE, description,\n\t\t\t\t\t\t\t\t\tnull);\n\t\t\t\t\t\t\t\tthrow new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());\n\t\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t\t.bodyToMono(DefaultReactiveOAuth2UserService.STRING_OBJECT_MAP)\n\t\t\t\t\t.mapNotNull((attributes) -> this.attributesConverter.convert(userRequest).convert(attributes));\n\t\t\treturn userAttributes.map((attrs) -> {\n\t\t\t\tGrantedAuthority authority = new OAuth2UserAuthority(attrs, userNameAttributeName);\n\t\t\t\tSet<GrantedAuthority> authorities = new HashSet<>();\n\t\t\t\tauthorities.add(authority);\n\t\t\t\tOAuth2AccessToken token = userRequest.getAccessToken();\n\t\t\t\tfor (String scope : token.getScopes()) {\n\t\t\t\t\tauthorities.add(new SimpleGrantedAuthority(\"SCOPE_\" + scope));\n\t\t\t\t}\n\n\t\t\t\treturn new DefaultOAuth2User(authorities, attrs, userNameAttributeName);\n\t\t\t})\n\t\t\t.onErrorMap((ex) -> (ex instanceof UnsupportedMediaTypeException\n\t\t\t\t\t|| (ex.getCause() != null && ex.getCause() instanceof UnsupportedMediaTypeException)), (ex) -> {\n\t\t\t\tUnsupportedMediaTypeException umte = (ex instanceof UnsupportedMediaTypeException)","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/userinfo/DefaultReactiveOAuth2UserService.java#L109-L145","documentation":"DefaultReactiveOAuth2UserService.loadUser registers an onStatus handler that parses an error response when the UserInfo endpoint returns an HTTP error status. If the body contains a UserInfo error (WWW-Authenticate/OAuth2 error object), it throws OAuth2AuthenticationException with code 'invalid_user_info_response' and the provider-supplied error description as the message.","triggerScenarios":"The WebClient call to the UserInfo uri returns an error status (4xx/5xx) whose response parses into a UserInfoErrorResponse — e.g. 401 with 'invalid_token' in WWW-Authenticate — during reactive loadUser.","commonSituations":"Expired or revoked access token sent to UserInfo; insufficient scopes for the userinfo claim; token issued for a different audience; provider rejecting the Bearer header format.","solutions":["Read the description for the provider's error code (e.g. invalid_token) and act: if 401 invalid_token, refresh the access token via the reactive authorized client manager and retry.","Verify the token's scopes include openid/profile (or whatever claims you need) and request them at authorization time.","Confirm the token audience/issuer matches the UserInfo endpoint you are calling.","Handle OAuth2AuthenticationException in your authentication failure handler with a user-facing message instead of leaking the raw error."],"exampleFix":"// before\nreturn userService.loadUser(userRequest); // throws on 401 invalid_token\n\n// after\nreturn authorizedClientManager.authorize(OAuth2AuthorizeRequest\n        .withClientRegistrationId(registrationId).principal(principal).build())\n    .flatMap(authorizedClient -> {\n        if (authorizedClient.getAccessToken().getScopes().containsAll(requiredScopes)) {\n            return userService.loadUser(userRequest);\n        }\n        return Mono.error(new AuthenticationServiceException(\"Missing scopes for UserInfo\"));\n    });","handlingStrategy":"try-catch","validationCode":"OAuth2AccessToken token = authorizedClient.getAccessToken();\nboolean tokenFresh = token != null\n    && token.getExpiresAt() != null\n    && token.getExpiresAt().isAfter(Instant.now().plusSeconds(30));\nif (!tokenFresh) {\n    // refresh via ReactiveOAuth2AuthorizedClientManager before loadUser\n}","typeGuard":null,"tryCatchPattern":".onErrorResume(OAuth2AuthenticationException.class, ex -> {\n    if (ex.getError().getDescription().contains(\"invalid_token\")) {\n        return refreshAndRetry(userRequest); // re-authorize then loadUser again\n    }\n    return Mono.error(ex);\n})","preventionTips":["Refresh access tokens before they expire via the authorized client manager","Request openid/profile/email scopes needed by the UserInfo endpoint","Check token audience/issuer matches the provider","Map OAuth2AuthenticationException to a friendly login-failure page"],"tags":["oauth2","oidc","userinfo","http-error","reactive","spring-security"],"backgroundTag":"http-error-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"}