apolloconfig/apollo · error · UsernameNotFoundException

User {username} not found in directory.

Error message

User {username} not found in directory.

What it means

Thrown by FilterLdapByGroupUserSearch.searchForUser() at line 93 when the LDAP group membership attribute is NOT 'memberUid' (i.e., DN-based membership like 'member'), and after iterating all member DNs from the group, none has an RDN value matching the supplied username. This means the user exists in LDAP but is not a member of the configured group. UsernameNotFoundException propagates up and Spring Security typically wraps it into a BadCredentialsException.

Source

Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/spi/ldap/FilterLdapByGroupUserSearch.java:93

  @Override
  public DirContextOperations searchForUser(String username) {
    if (logger.isDebugEnabled()) {
      logger.debug("Searching for user '{}', with user search {}", username, this);
    }
    SpringSecurityLdapTemplate template = new SpringSecurityLdapTemplate(this.contextSource);
    template.setSearchControls(searchControls);
    return template.searchForObject(groupBase, groupSearch, ctx -> {
      if (!MEMBER_UID_ATTR_NAME.equals(groupMembershipAttrName)) {
        String[] members = ((DirContextAdapter) ctx).getStringAttributes(groupMembershipAttrName);
        for (String item : members) {
          LdapName memberDn = LdapUtils.newLdapName(item);
          LdapName memberRdn = LdapUtils.removeFirst(memberDn, LdapUtils.newLdapName(searchBase));
          String rdnValue = LdapUtils.getValue(memberRdn, rdnKey).toString();
          if (rdnValue.equalsIgnoreCase(username)) {
            return new DirContextAdapter(memberRdn.toString());
          }
        }
        throw new UsernameNotFoundException("User " + username + " not found in directory.");
      }
      String[] memberUids = ((DirContextAdapter) ctx).getStringAttributes(groupMembershipAttrName);
      for (String memberUid : memberUids) {
        if (memberUid.equalsIgnoreCase(username)) {
          Name name = searchUserById(memberUid);
          LdapName ldapName = LdapUtils.newLdapName(name);
          LdapName ldapRdn = LdapUtils.removeFirst(ldapName, LdapUtils.newLdapName(searchBase));
          return new DirContextAdapter(ldapRdn);
        }
      }
      throw new UsernameNotFoundException("User " + username + " not found in directory.");
    });
  }
}

View on GitHub (pinned to d95fc18d11)

Solutions

  1. Add the user to the LDAP group configured as the Apollo access group.
  2. Verify the LDAP configuration: groupMembershipAttrName, rdnKey, and searchBase match your directory schema.
  3. Check that LdapUtils.removeFirst(memberDn, searchBase) correctly produces a relative DN whose rdnKey value matches the login username.

Example fix

// Not a code fix — add the user to the configured LDAP group in your directory service (e.g., Active Directory or OpenLDAP).
Defensive patterns

Strategy: try-catch

Validate before calling

// LDAP group membership cannot be validated client-side; verify directory config instead.
// Ensure groupMembershipAttrName and rdnKey match your LDAP schema before deploying.

Try / catch

try {
    authenticationManager.authenticate(
        new UsernamePasswordAuthenticationToken(username, password));
} catch (AuthenticationException e) {
    Throwable cause = e;
    while (cause != null) {
        if (cause instanceof UsernameNotFoundException
                && cause.getMessage().contains("not found in directory")) {
            return ResponseEntity.status(401).body("User is not a member of the authorized LDAP group");
        }
        cause = cause.getCause();
    }
    throw e;
}

Prevention

When it happens

Trigger: A user authenticates via LDAP group-filtered search where groupMembershipAttrName is DN-based (e.g., 'member'). The LDAP group object is found and its members enumerated, but the username doesn't match any member DN's RDN value (extracted via rdnKey). Common when the user is not in the authorized Apollo access group.

Common situations: User was removed from the LDAP/AD group that grants Apollo access but still has an LDAP account. The rdnKey or groupMembershipAttrName configuration doesn't match the actual LDAP schema. The user's DN structure doesn't match the expected searchBase for RDN extraction.

Related errors


AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14). Data as JSON: /api/errors/bb29bd3a0129641b. Report an issue: GitHub.