apereo/cas · error · LoginException
Principal id attribute is not found for [principalAttr]
Error message
Principal id attribute is not found for [principalAttr]
What it means
During principal construction, getLdapPrincipalIdentifier reads the configured principalIdAttribute from the LDAP entry. When the attribute is missing and CAS is configured to disallow missing principal id attributes (allowMissingPrincipalAttributeValues=false), it throws LoginException 'Principal id attribute is not found'.
Solutions
- Set principal-id-attribute to an attribute actually present on the entry (verify with ldapsearch).
- Enable allow-missing-principal-attribute-values=true so CAS falls back to the provided user id.
- Add the attribute to returned-attributes / ensure the ACL allows reading it.
- Fix casing/typo of the attribute name in the configuration.
Example fix
// before cas.authn.ldap[0].principal-id-attribute=employeeId cas.authn.ldap[0].allow-missing-principal-attribute-values=false // after cas.authn.ldap[0].principal-id-attribute=sAMAccountName cas.authn.ldap[0].allow-missing-principal-attribute-values=true
Defensive patterns
Strategy: validation
Validate before calling
// ensure the attribute is present before configuring it as principal id
SearchResult sr = connectionFactory.search(
new SearchRequest(baseDn, userFilter, "sAMAccountName"));
LdapEntry entry = sr.getResult().getEntry();
if (!entry.getAttributes().containsKey(principalIdAttribute)) {
throw new IllegalStateException("Attribute missing: " + principalIdAttribute);
} Try / catch
try { result = handler.authenticate(credential); }
catch (LoginException e) { if (e.getMessage().startsWith("Principal id attribute")) { fixPrincipalIdConfig(); } } Prevention
- ldapsearch a sample user to confirm the principal-id attribute exists and is returned.
- Set allow-missing-principal-attribute-values=true for resilience.
- Include the attribute in returned-attributes and confirm ACLs permit reading it.
When it happens
Trigger: cas.authn.ldap[].principal-id-attribute names an attribute absent from the authenticated entry (or empty), and allow-missing-principal-attribute-values is false, so the code cannot fall back to the username.
Common situations: Attribute not returned by the directory (not in returned-attributes list, wrong case, or simply not populated for the user); typo in principal-id-attribute name; after migration where the attribute (e.g. sAMAccountName vs uid) differs.
Related errors
- Multiple principal values are not allowed: [principalAttr]
- Could not locate an LDAP entry for [filter] and base DN…
- LDAP url cannot be empty/blank
- Base dn cannot be empty/blank for authenticated/anonymous…
- User filter cannot be empty/blank for…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/1cbb3963c25d641a.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authentication/LdapAuthenticationHandler.java:208
* @param ldapEntry the ldap entry
* @return the ldap principal identifier
* @throws LoginException in case the principal id cannot be determined.
*/
protected String getLdapPrincipalIdentifier(final String username, final LdapEntry ldapEntry) throws LoginException {
if (StringUtils.isNotBlank(this.principalIdAttribute)) {
val principalAttr = ldapEntry.getAttribute(this.principalIdAttribute);
if (principalAttr == null || principalAttr.size() == 0) {
if (this.allowMissingPrincipalAttributeValue) {
LOGGER.warn("The principal id attribute [{}] is not found. CAS cannot construct the final authenticated principal "
+ "if it's unable to locate the attribute that is designated as the principal id. "
+ "Attributes available on the LDAP entry are [{}]. Since principal id attribute is not available, CAS will "
+ "fall back to construct the principal based on the provided user id: [{}]",
this.principalIdAttribute, ldapEntry.getAttributes(), username);
return username;
}
LOGGER.error("The principal id attribute [{}] is not found. CAS is configured to disallow missing principal attributes",
this.principalIdAttribute);
throw new LoginException("Principal id attribute is not found for " + principalAttr);
}
val value = principalAttr.getStringValue();
if (principalAttr.size() > 1) {
if (!this.allowMultiplePrincipalAttributeValues) {
throw new LoginException("Multiple principal values are not allowed: " + principalAttr);
}
LOGGER.warn("Found multiple values for principal id attribute: [{}]. Using first value=[{}].", principalAttr, value);
}
LOGGER.debug("Retrieved principal id attribute [{}]", value);
return value;
}
LOGGER.debug("Principal id attribute is not defined. Using the default provided user id [{}]", username);
return username;
}
private AuthenticationResponse getLdapAuthenticationResponse(final UsernamePasswordCredential upc) throws PreventedException {
try {
LOGGER.debug("Attempting LDAP authentication for [{}]. Authenticator pre-configured attributes are [{}], "View on GitHub (pinned to e7288fc434)