{"record":{"id":"bf5385b24d8c0963","repo":"apereo/cas","slug":"attribute-not-found-or-has-no-values","errorCode":null,"errorMessage":"Attribute [{}] not found or has no values","messagePattern":"Attribute \\[(.+?)\\] not found or has no values","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-surrogate-authentication-ldap/src/main/java/org/apereo/cas/authentication/surrogate/SurrogateLdapAuthenticationService.java","lineNumber":84,"sourceCode":"        for (val ldap : ldapProperties) {\n            try (val connectionFactory = new LdapConnectionFactory(LdapUtils.newLdaptiveConnectionFactory(ldap))) {\n                val filter = LdapUtils.newLdaptiveSearchFilter(ldap.getSearchFilter(), CollectionUtils.wrap(username));\n                LOGGER.debug(\"Using search filter to find eligible accounts: [{}]\", filter);\n\n                val response = connectionFactory.executeSearchOperation(ldap.getBaseDn(), filter, ldap.getPageSize());\n                LOGGER.debug(\"LDAP response: [{}]\", response);\n\n                if (!LdapUtils.containsResultEntry(response)) {\n                    LOGGER.warn(\"LDAP response is not found or does not contain a result entry for [{}]\", username);\n                    return new ArrayList<>();\n                }\n\n                val ldapEntry = response.getEntry();\n                val attribute = ldapEntry.getAttribute(ldap.getMemberAttributeName());\n                LOGGER.debug(\"Locating LDAP entry [{}] with attribute [{}]\", ldapEntry, attribute);\n\n                if (attribute == null || attribute.getStringValues().isEmpty()) {\n                    LOGGER.warn(\"Attribute [{}] not found or has no values\", ldap.getMemberAttributeName());\n                    return new ArrayList<>();\n                }\n\n                val pattern = RegexUtils.createPattern(ldap.getMemberAttributeValueRegex());\n                LOGGER.debug(\"Constructed attribute value regex pattern [{}]\", pattern.pattern());\n                val eligible = attribute.getStringValues()\n                    .stream()\n                    .map(pattern::matcher)\n                    .filter(Matcher::matches)\n                    .map(p -> {\n                        if (p.groupCount() > 0) {\n                            return p.group(1);\n                        }\n                        return p.group();\n                    })\n                    .sorted()\n                    .collect(Collectors.toList());\n                LOGGER.debug(\"Following accounts may be eligible for surrogate authentication: [{}]\", eligible);","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-surrogate-authentication-ldap/src/main/java/org/apereo/cas/authentication/surrogate/SurrogateLdapAuthenticationService.java#L66-L102","documentation":"After finding the user's LDAP entry, SurrogateLdapAuthenticationService reads the configured member attribute (e.g. the multi-valued attribute listing accounts the user may impersonate). If the attribute is absent on the entry or has no values, this warning is logged and an empty surrogate account list is returned, blocking impersonation for that user.","triggerScenarios":"getImpersonationAccounts gets a valid LDAP entry but ldapEntry.getAttribute(memberAttributeName) returns null or attribute.getStringValues() is empty - the entry exists but was never populated with the surrogate member values.","commonSituations":"member-attribute-name misconfigured (typo or attribute not in schema); LDAP admins never granted the user impersonation rights; attribute stored as binary/different syntax so string values are empty; replication lag on a read replica.","solutions":["Confirm member-attribute-name matches a real, populated attribute on the user entry (inspect with ldapsearch).","Grant the user the surrogate membership values in LDAP per your provisioning process.","Check the attribute's syntax (string vs binary) and LDAP schema mapping.","Verify you are querying a current replica, not a lagging one."],"exampleFix":"// before\ncas.authn.surrogate.ldap[0].member-attribute-name=memberOf\n// after\ncas.authn.surrogate.ldap[0].member-attribute-name=casSurrogateMember","handlingStrategy":"validation","validationCode":"Attributes attrs = entry.getAttributes();\nif (attrs.get(memberAttr) == null || !attrs.get(memberAttr).getAll().hasMore()) {\n    // user has no surrogate grants; skip impersonation path\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify member-attribute-name against real schema","Provision surrogate grants during onboarding","Check attribute syntax (string vs binary)"],"tags":["ldap","surrogate","missing-attribute","impersonation"],"backgroundTag":"empty-result-set","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}