apereo/cas · warning

LDAP response is not found or does not contain a result…

Error message

LDAP response is not found or does not contain a result entry for [{}]

What it means

SurrogateLdapAuthenticationService searches LDAP for the acting user's entry to read the member attribute listing impersonatable accounts. When the search response contains no entry (no match or search failure surfaced as empty response), it logs this warning and returns an empty account list, meaning surrogate (impersonation) login will be denied for that user.

Solutions

  1. Verify base-dn and search-filter in cas.authn.surrogate.ldap config actually contain the target user.
  2. Run the same filter with ldapsearch using the CAS bind credentials to see whether an entry returns.
  3. Confirm the user's LDAP entry carries the expected member attribute / surrogate authorization data.
  4. Check bind DN permissions can read the user entry under the configured base.

Example fix

// before
cas.authn.surrogate.ldap[0].base-dn=ou=people,dc=example,dc=org
cas.authn.surrogate.ldap[0].search-filter=(uid={user})
// after  # uid replaced with sAMAccountName to match directory schema
cas.authn.surrogate.ldap[0].base-dn=ou=people,dc=example,dc=org
cas.authn.surrogate.ldap[0].search-filter=(sAMAccountName={user})
Defensive patterns

Strategy: validation

Validate before calling

// pre-check with ldapsearch using CAS bind credentials
// ldapsearch -H ldaps://dir -D binddn -w pw -b 'ou=people,dc=example,dc=org' '(uid=jdoe)'

Prevention

When it happens

Trigger: getImpersonationAccounts executes a search with the configured baseDn and surrogate-enabled filter, and LdapUtils.containsResultEntry(response) is false - the user DN is outside baseDn, the filter matches nothing, or the entry lacks object visibility to the bind account.

Common situations: Wrong surrogate search base DN or search filter in cas.authn.surrogate.ldap[...]; user attribute (e.g. surrogateMemberOf not populated in LDAP); bind account lacking read rights on the entry; searching the wrong LDAP branch after an org restructure.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-surrogate-authentication-ldap/src/main/java/org/apereo/cas/authentication/surrogate/SurrogateLdapAuthenticationService.java:75

                LoggingUtils.error(LOGGER, e);
            }
        }
        return false;
    }

    @Override
    public Collection<String> getImpersonationAccounts(final String username, final Optional<? extends Service> service) {
        val ldapProperties = casProperties.getAuthn().getSurrogate().getLdap();
        for (val ldap : ldapProperties) {
            try (val connectionFactory = new LdapConnectionFactory(LdapUtils.newLdaptiveConnectionFactory(ldap))) {
                val filter = LdapUtils.newLdaptiveSearchFilter(ldap.getSearchFilter(), CollectionUtils.wrap(username));
                LOGGER.debug("Using search filter to find eligible accounts: [{}]", filter);

                val response = connectionFactory.executeSearchOperation(ldap.getBaseDn(), filter, ldap.getPageSize());
                LOGGER.debug("LDAP response: [{}]", response);

                if (!LdapUtils.containsResultEntry(response)) {
                    LOGGER.warn("LDAP response is not found or does not contain a result entry for [{}]", username);
                    return new ArrayList<>();
                }

                val ldapEntry = response.getEntry();
                val attribute = ldapEntry.getAttribute(ldap.getMemberAttributeName());
                LOGGER.debug("Locating LDAP entry [{}] with attribute [{}]", ldapEntry, attribute);

                if (attribute == null || attribute.getStringValues().isEmpty()) {
                    LOGGER.warn("Attribute [{}] not found or has no values", ldap.getMemberAttributeName());
                    return new ArrayList<>();
                }

                val pattern = RegexUtils.createPattern(ldap.getMemberAttributeValueRegex());
                LOGGER.debug("Constructed attribute value regex pattern [{}]", pattern.pattern());
                val eligible = attribute.getStringValues()
                    .stream()
                    .map(pattern::matcher)
                    .filter(Matcher::matches)

View on GitHub (pinned to e7288fc434)