{"record":{"id":"d8d94e4d9fe42bb8","repo":"apereo/cas","slug":"could-not-locate-ldap-attribute-for","errorCode":null,"errorMessage":"Could not locate LDAP attribute [{}] for [{}]","messagePattern":"Could not locate LDAP attribute \\[(.+?)\\] for \\[(.+?)\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-pm-ldap/src/main/java/org/apereo/cas/pm/LdapPasswordManagementService.java","lineNumber":194,"sourceCode":"                                   final List<String> attributeNames,\n                                   final List<String> ldapFilterParam) {\n        return findEntries(ldapFilterParam, false)\n            .keySet()\n            .stream()\n            .map(entry -> {\n                LOGGER.debug(\"Found LDAP entry [{}] to use\", entry);\n                return attributeNames\n                    .stream()\n                    .map(attributeName -> SpringExpressionLanguageValueResolver.getInstance().resolve(attributeName))\n                    .map(attributeName -> {\n                        val attr = entry.getAttribute(attributeName);\n                        if (attr != null) {\n                            val attributeValue = attr.getStringValue();\n                            LOGGER.debug(\"Found [{}] [{}] for user [{}].\", attributeName,\n                                attributeValue, context.getUsername());\n                            return attributeValue;\n                        }\n                        LOGGER.warn(\"Could not locate LDAP attribute [{}] for [{}]\",\n                            attributeName, entry.getDn());\n                        return null;\n                    })\n                    .filter(Objects::nonNull)\n                    .findFirst()\n                    .orElse(null);\n            })\n            .filter(Objects::nonNull)\n            .findFirst()\n            .orElse(null);\n    }\n\n    protected Map<LdapEntry, LdapPasswordManagementProperties> findEntries(\n        final List<String> filterValues, final boolean transform) {\n        val results = new LinkedHashMap<LdapEntry, LdapPasswordManagementProperties>();\n        casProperties.getAuthn().getPm().getLdap()\n            .stream()\n            .sorted(Comparator.comparing(LdapPasswordManagementProperties::getName))","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-pm-ldap/src/main/java/org/apereo/cas/pm/LdapPasswordManagementService.java#L176-L212","documentation":"The internal findAttribute helper searches the LDAP entry returned for the user and reads the requested attribute's string value. When the entry exists but does not contain the configured attribute (attr == null), it logs this warn and returns null, propagating 'attribute missing' to findEmails/findPhone/findUsername callers.","triggerScenarios":"LDAP search succeeds and returns the user's entry, but entry.get(attributeName) is null — the schema/objectClass of the entry simply has no value for the configured attribute name.","commonSituations":"cas.authn.pm.reset.mail/sms.attributeName points at an attribute the user entries never populate (e.g. mobile not set); attribute name typo or wrong case; entries belong to an objectClass lacking that attribute; attribute hidden by ACLs/anonymous search limits.","solutions":["Verify the attribute exists and is populated on the user's DN in the directory (ldapsearch as the configured bind user)","Fix cas.authn.pm.reset.mail.attributeName / sms.attributeName to match the directory schema exactly","Extend the entry's objectClass or populate the attribute for affected users","Check ACLs so the PM bind account can read the attribute"],"exampleFix":"// before\ncas.authn.pm.reset.sms.attributeName=telephoneNumber\n// entries only populate 'mobile'\n// after\ncas.authn.pm.reset.sms.attributeName=mobile","handlingStrategy":"fallback","validationCode":"// pre-flight: confirm the attribute is readable before triggering flows\nAttributes a = ctx.getAttributes(userDn, new String[]{attributeName});\nif (a.get(attributeName) == null) {\n    log.warn(\"User {} has no {} attribute\", userDn, attributeName);\n}","typeGuard":null,"tryCatchPattern":"String v = pmService.findPhone(query);\nif (v == null) { log.info(\"No phone attribute; falling back to email flow\"); }","preventionTips":["ldapsearch with the PM bind account to confirm attribute visibility before configuring","Match attributeName values exactly to directory schema (case included)","Populate mail/mobile during account provisioning so PM always has a contact"],"tags":["ldap","attribute-not-found","password-management"],"backgroundTag":"record-not-found","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"}