apereo/cas · error · IllegalStateException

Could not locate an LDAP entry for [filter] and base DN…

Error message

Could not locate an LDAP entry for [filter] and base DN [baseDn]

What it means

Before modifying the password, the post-processor searches LDAP for the user entry using the configured filter and base DN. If the search returns no entry, it throws an IllegalStateException: the account whose password was to be synchronized does not exist in that subtree.

Solutions

  1. Verify the search filter matches a real entry: run ldapsearch with the same filter and base DN using the configured bind credentials
  2. Correct cas.authn.ldap[x].base-dn to the OU containing user entries
  3. Align the user filter attribute with the actual naming/principal attribute (uid vs sAMAccountName vs cn)
  4. Skip password synchronization for users not in this directory (restrict the handler's applicable authentication sources)
  5. Log the resolved DN and filter to confirm what was actually searched

Example fix

// before
// base-dn=dc=example,dc=org
// user-filter=(uid={user})
// after
// base-dn=ou=people,dc=example,dc=org
// user-filter=(sAMAccountName={user})
Defensive patterns

Strategy: validation

Validate before calling

// before enabling sync, confirm the user resolves
SearchResult entry = LdapUtils.getLdapEntry(ldapProperties, filter);
if (entry == null) throw new IllegalStateException("No LDAP entry for filter " + filter);
String dn = entry.getDn();

Try / catch

try {
    postProcessor.process(authentication);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("Could not locate an LDAP entry")) {
        // skip sync for users outside this directory / alert on filter-base mismatch
    }
} else if (e instanceof AuthenticationException ae) { /* fatal path */ }

Prevention

When it happens

Trigger: process() runs after authentication but the search filter (e.g. (uid={0}) or (mail={user})) matches nothing under ldapProperties.getBaseDn() — wrong base DN, wrong filter attribute, user lives in a different OU, or the bind DN cannot see that subtree.

Common situations: Base DN missing an OU segment (ou=people forgotten); authenticated user authenticated via another handler (different backend) but the LDAP sync handler still runs; case/attribute mismatch between CAS principal id and directory uid.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/0c14fac515200ac6. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authentication/LdapPasswordSynchronizationAuthenticationPostProcessor.java:71

            if (LdapUtils.containsResultEntry(response)) {
                val dn = response.getEntry().getDn();
                LOGGER.debug("Updating account password for [{}]", dn);

                val operation = new ModifyOperation(searchFactory.getConnectionFactory());
                val mod = new AttributeModification(AttributeModification.Type.REPLACE, getLdapPasswordAttribute(credential));
                val updateResponse = operation.execute(new ModifyRequest(dn, mod));
                LOGGER.trace("Result code [{}], message: [{}]", response.getResultCode(), response.getDiagnosticMessage());
                val result = updateResponse.getResultCode() == ResultCode.SUCCESS;
                if (!result) {
                    val message = String.format("Could not update the LDAP entry's password for %s and base DN %s: %s",
                        filter.format(), ldapProperties.getBaseDn(), updateResponse.getDiagnosticMessage());
                    throw new IllegalStateException(message);
                }
                LOGGER.info("Updated the LDAP entry's password for [{}] and base DN [{}]", filter.format(), ldapProperties.getBaseDn());
            } else {
                val message = String.format("Could not locate an LDAP entry for %s and base DN %s", filter.format(), ldapProperties.getBaseDn());
                throw new IllegalStateException(message);
            }
        } catch (final Exception e) {
            LoggingUtils.error(LOGGER, e);
            if (ldapProperties.isPasswordSynchronizationFailureFatal()) {
                throw new AuthenticationException(e);
            }

        }
    }

    @Override
    public boolean supports(final Credential credential) {
        return credential instanceof UsernamePasswordCredential;
    }

    protected LdapAttribute getLdapPasswordAttribute(final UsernamePasswordCredential credential) {
        if ("unicodePwd".equals(ldapProperties.getPasswordAttribute())) {
            return new UnicodePwdAttribute(credential.toPassword());

View on GitHub (pinned to e7288fc434)