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

  1. Set principal-id-attribute to an attribute actually present on the entry (verify with ldapsearch).
  2. Enable allow-missing-principal-attribute-values=true so CAS falls back to the provided user id.
  3. Add the attribute to returned-attributes / ensure the ACL allows reading it.
  4. 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

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


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)