{"record":{"id":"34944f1cd99af83a","repo":"spring-projects/spring-security","slug":"missing-user-name-attribute","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/DefaultOAuth2UserService.java","lineNumber":189,"sourceCode":"\tprivate String getUserNameAttributeName(OAuth2UserRequest userRequest) {\n\t\tif (!StringUtils\n\t\t\t.hasText(userRequest.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri())) {\n\t\t\tOAuth2Error oauth2Error = new OAuth2Error(MISSING_USER_INFO_URI_ERROR_CODE,\n\t\t\t\t\t\"Missing required UserInfo Uri in UserInfoEndpoint for Client Registration: \"\n\t\t\t\t\t\t\t+ userRequest.getClientRegistration().getRegistrationId(),\n\t\t\t\t\tnull);\n\t\t\tthrow new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());\n\t\t}\n\t\tString userNameAttributeName = userRequest.getClientRegistration()\n\t\t\t.getProviderDetails()\n\t\t\t.getUserInfoEndpoint()\n\t\t\t.getUserNameAttributeName();\n\t\tif (!StringUtils.hasText(userNameAttributeName)) {\n\t\t\tOAuth2Error oauth2Error = new OAuth2Error(MISSING_USER_NAME_ATTRIBUTE_ERROR_CODE,\n\t\t\t\t\t\"Missing required \\\"user name\\\" attribute name in UserInfoEndpoint for Client Registration: \"\n\t\t\t\t\t\t\t+ userRequest.getClientRegistration().getRegistrationId(),\n\t\t\t\t\tnull);\n\t\t\tthrow new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());\n\t\t}\n\t\treturn userNameAttributeName;\n\t}\n\n\tprivate Collection<GrantedAuthority> getAuthorities(OAuth2AccessToken token, Map<String, Object> attributes,\n\t\t\tString userNameAttributeName) {\n\t\tCollection<GrantedAuthority> authorities = new LinkedHashSet<>();\n\t\tauthorities.add(new OAuth2UserAuthority(attributes, userNameAttributeName));\n\t\tfor (String authority : token.getScopes()) {\n\t\t\tauthorities.add(new SimpleGrantedAuthority(\"SCOPE_\" + authority));\n\t\t}\n\t\treturn authorities;\n\t}\n\n\t/**\n\t * Sets the {@link Converter} used for converting the {@link OAuth2UserRequest} to a\n\t * {@link RequestEntity} representation of the UserInfo Request.\n\t * @param requestEntityConverter the {@link Converter} used for converting to a","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/userinfo/DefaultOAuth2UserService.java#L171-L207","documentation":"DefaultOAuth2UserService.getUserNameAttributeName requires a user name attribute name configured on UserInfoEndpoint; this attribute selects which claim in the UserInfo JSON response becomes the principal name and is used to build the OAuth2UserAuthority. When it is missing/blank, the service throws OAuth2AuthenticationException with code 'missing_user_name_attribute' because it cannot determine the user's name key.","triggerScenarios":"ClientRegistration has a valid user-info-uri but userInfoEndpoint().userNameAttributeName() is null/empty when loadUser runs for the user-info flow.","commonSituations":"Spring Boot autoconfig can't infer user-name-attribute for unknown providers, leaving it unset; manual ClientRegistration code omits userNameAttributeName; providers using non-standard keys (e.g. 'login', 'email', 'sub') where the developer assumed a default exists.","solutions":["Set the user name attribute to a claim the UserInfo response actually returns: spring.security.oauth2.client.provider.<id>.user-name-attribute=sub (or programmatically userInfoEndpoint().userNameAttributeName(\"sub\")).","Check the provider's UserInfo response (curl with a token) and pick an existing top-level claim key such as sub, email, preferred_username, login, or id.","If using issuer-uri discovery, verify the discovered end_session/userinfo metadata includes user_name_attribute_name; otherwise set it manually.","Add a startup check of ClientRegistrations to fail fast on missing userNameAttributeName."],"exampleFix":"// before\nClientRegistration.withRegistrationId(\"myidp\")\n    .userInfoEndpoint() // no userNameAttributeName\n    .and()...\n\n// after\nClientRegistration.withRegistrationId(\"myidp\")\n    ...\n    .userInfoEndpoint()\n        .uri(\"https://idp.example.com/userinfo\")\n        .userNameAttributeName(\"sub\")\n        .and()\n    .build();","handlingStrategy":"validation","validationCode":"Map<String,Object> claims = fetchUserInfoOnce(token); // one-off check\nif (!claims.containsKey(\"sub\")) {\n    throw new IllegalStateException(\"Provider does not return 'sub'; pick an existing claim for user-name-attribute\");\n}","typeGuard":null,"tryCatchPattern":"catch (OAuth2AuthenticationException ex) {\n    if (\"missing_user_name_attribute\".equals(ex.getError().getErrorCode())) {\n        // set user-name-attribute for this registration before redeploying\n    }\n}","preventionTips":["Always set user-name-attribute alongside user-info-uri","Confirm the chosen claim exists in the real UserInfo response","Document per-provider attribute names (sub, login, email, id)","Add a startup validation of userNameAttributeName for every registration"],"tags":["oauth2","oidc","configuration","userinfo","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"}