{"record":{"id":"363f8c908e39fef4","repo":"spring-projects/spring-security","slug":"missing-user-info-uri-363f8c","errorCode":"missing_user_info_uri","errorMessage":"Missing required UserInfo Uri in UserInfoEndpoint for Client Registration: ${registrationId}","messagePattern":"Missing required UserInfo Uri in UserInfoEndpoint for Client Registration: (.+?)","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":100,"sourceCode":"\tprivate Converter<OAuth2UserRequest, Converter<Map<String, Object>, Map<String, Object>>> attributesConverter = (\n\t\t\trequest) -> (attributes) -> attributes;\n\n\tprivate WebClient webClient = WebClient.create();\n\n\t@Override\n\tpublic Mono<OAuth2User> loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {\n\t\treturn Mono.defer(() -> {\n\t\t\tAssert.notNull(userRequest, \"userRequest cannot be null\");\n\t\t\tString userInfoUri = userRequest.getClientRegistration()\n\t\t\t\t.getProviderDetails()\n\t\t\t\t.getUserInfoEndpoint()\n\t\t\t\t.getUri();\n\t\t\tif (!StringUtils.hasText(userInfoUri)) {\n\t\t\t\tOAuth2Error oauth2Error = new OAuth2Error(MISSING_USER_INFO_URI_ERROR_CODE,\n\t\t\t\t\t\t\"Missing required UserInfo Uri in UserInfoEndpoint for Client Registration: \"\n\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\tString userNameAttributeName = userRequest.getClientRegistration()\n\t\t\t\t.getProviderDetails()\n\t\t\t\t.getUserInfoEndpoint()\n\t\t\t\t.getUserNameAttributeName();\n\t\t\tif (!StringUtils.hasText(userNameAttributeName)) {\n\t\t\t\tOAuth2Error oauth2Error = new OAuth2Error(MISSING_USER_NAME_ATTRIBUTE_ERROR_CODE,\n\t\t\t\t\t\t\"Missing required \\\"user name\\\" attribute name in UserInfoEndpoint for Client Registration: \"\n\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);","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/userinfo/DefaultReactiveOAuth2UserService.java#L82-L118","documentation":"DefaultReactiveOAuth2UserService.loadUser validates that the ClientRegistration's UserInfoEndpoint has a non-empty uri before issuing the reactive UserInfo request. If userInfoUri is blank it throws OAuth2AuthenticationException with code 'missing_user_info_uri'. The reactive user-info flow cannot proceed without an endpoint to fetch the authenticated user's claims.","triggerScenarios":"In a WebFlux/reactive app, ServerOAuth2LoginAuthenticationWebFilter triggers user-info based login while the ClientRegistration (from ReactiveClientRegistrationRepository / spring config) lacks user-info-uri.","commonSituations":"Reactive OAuth2 login with a manually defined provider missing user-info-uri; provider metadata discovery (issuer-uri) failing silently so userinfo_endpoint absent; non-OIDC OAuth2 provider configured reactively without explicit userinfo endpoint.","solutions":["Add user-info-uri to provider config (spring.security.oauth2.client.provider.<id>.user-info-uri) or via ClientRegistration userInfoEndpoint().uri(...).","Use issuer-uri based registration so userinfo_endpoint is discovered from .well-known/openid-configuration.","If the id_token already contains all needed claims, ensure the flow uses OIDC id-token parsing instead of the UserInfo path.","Validate registrations at application startup to surface the missing uri before first login."],"exampleFix":"// before (reactive)\nspring.security.oauth2.client.provider.myidp.token-uri=https://idp.example.com/token\n# user-info-uri missing\n\n// after\nspring.security.oauth2.client.provider.myidp.authorization-uri=https://idp.example.com/authorize\nspring.security.oauth2.client.provider.myidp.token-uri=https://idp.example.com/token\nspring.security.oauth2.client.provider.myidp.user-info-uri=https://idp.example.com/userinfo\nspring.security.oauth2.client.provider.myidp.user-name-attribute=sub","handlingStrategy":"validation","validationCode":"ClientRegistration reg = reactiveRepository.findByRegistrationId(\"myclient\").block();\nif (reg == null || !StringUtils.hasText(reg.getProviderDetails().getUserInfoEndpoint().getUri())) {\n    throw new IllegalStateException(\"reactive registration myclient is missing user-info-uri\");\n}","typeGuard":null,"tryCatchPattern":"catch (OAuth2AuthenticationException ex) {\n    if (\"missing_user_info_uri\".equals(ex.getError().getErrorCode())) {\n        // configuration defect: surface at startup, not at login time\n    }\n}","preventionTips":["Use issuer-uri based reactive registration for OIDC providers","Fail application startup if any registration lacks user-info-uri","Test the full reactive login flow in CI against a stub provider","Keep reactive and servlet provider configs in sync when both exist"],"tags":["oauth2","oidc","webflux","configuration","spring-security"],"backgroundTag":"missing-required-config-field","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"}