{"record":{"id":"fbeaa2467a63ebcd","repo":"spring-projects/spring-security","slug":"missing-user-name-attribute-fbeaa2","errorCode":"missing_user_name_attribute","errorMessage":"Missing required \"user name\" attribute name in UserInfoEndpoint for Client Registration: ${registrationId}","messagePattern":"Missing required \"user name\" attribute name 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":111,"sourceCode":"\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);\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)","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/userinfo/DefaultReactiveOAuth2UserService.java#L93-L129","documentation":"DefaultReactiveOAuth2UserService.loadUser requires userNameAttributeName on UserInfoEndpoint to know which claim in the UserInfo JSON response identifies the end-user. When it is missing or blank, it throws OAuth2AuthenticationException with code 'missing_user_name_attribute' before building the WebClient request.","triggerScenarios":"Reactive OAuth2 login where the ClientRegistration has a valid user-info-uri but userInfoEndpoint().userNameAttributeName() is null/empty at loadUser time.","commonSituations":"Manual reactive ClientRegistration setup omitting userNameAttributeName; custom provider whose name claim differs (login, uid, preferred_username) and the developer assumed defaults; Spring Boot cannot infer the attribute for an unknown provider.","solutions":["Set user-name-attribute in provider config or userInfoEndpoint().userNameAttributeName(\"sub\") matching a claim the provider returns.","Inspect the actual UserInfo JSON response to choose the correct claim key.","If using discovery via issuer-uri, confirm the provider metadata and add the attribute manually if not inferred.","Add startup validation of all ClientRegistrations for required fields."],"exampleFix":"// before\nspring.security.oauth2.client.provider.myidp.user-info-uri=https://idp.example.com/userinfo\n\n// after\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().getUserNameAttributeName())) {\n    throw new IllegalStateException(\"reactive registration myclient is missing user-name-attribute\");\n}","typeGuard":null,"tryCatchPattern":"catch (OAuth2AuthenticationException ex) {\n    if (\"missing_user_name_attribute\".equals(ex.getError().getErrorCode())) {\n        // add userInfoEndpoint().userNameAttributeName(...) for this registration\n    }\n}","preventionTips":["Pair every user-info-uri with a user-name-attribute","Verify the attribute key exists in the provider's UserInfo JSON","Validate registrations at startup in reactive apps too","Use well-known claim names (sub) unless the provider mandates otherwise"],"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-14T11:17:12.474Z"}