apereo/cas · error · IllegalStateException

Principal attribute [

Error message

Principal attribute [

What it means

Thrown by JdbcAcceptableUsagePolicyRepository.determinePrincipalId when the configured cas.acceptable-usage-policy.jdbc.principal-id-column/attribute name does not exist among the authenticated principal's attributes. CAS uses this attribute to look up the AUP record keyed by an alternate principal identifier, so a missing attribute makes the mapping impossible. It surfaces as IllegalStateException from determinePrincipalId, invoked via principalId during AUP policy checks.

Solutions

  1. Verify the attribute name in cas.acceptable-usage-policy.jdbc.principal-id-attribute exactly matches an attribute the principal actually carries (check the attribute name and casing).
  2. Ensure the attribute is fetched and released: adjust the authentication/attribute repository source or service release policy so it appears on the principal before AUP evaluation.
  3. If the CAS principal id itself is the right key, remove/unset the principal-id-attribute so determinePrincipalId falls back to principal.getId().
  4. Log the full principal attribute map (or check the audit/inspektr logs) to see which attributes are actually available at AUP evaluation time.

Example fix

// before (application.properties)
cas.acceptable-usage-policy.jdbc.principal-id-attribute=employeeid

// after (attribute actually present on the principal)
cas.acceptable-usage-policy.jdbc.principal-id-attribute=employeeId
Defensive patterns

Strategy: validation

Validate before calling

// before enabling AUP-JDBC, confirm the attribute reaches the principal
if (!principal.getAttributes().containsKey(configuredPrincipalIdAttribute)) {
    throw new IllegalStateException("AUP principal-id attribute missing: " + configuredPrincipalIdAttribute);
}

Prevention

When it happens

Trigger: cas.acceptable-usage-policy.jdbc.principal-id-attribute is set to a name (e.g. 'employeeId') that is absent from principal.getAttributes() at the time the AUP repository resolves the principal id — typically after login when the attribute was never released into the principal.

Common situations: Typo in the attribute name in cas.properties; the attribute resolution strategy (source attribute release policy, LDAP/attribute repository config) does not actually fetch or release that attribute; casing mismatch between configured name and the attribute produced by the principal factory.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-aup-jdbc/src/main/java/org/apereo/cas/aup/JdbcAcceptableUsagePolicyRepository.java:104

     * @return the acceptable usage policy column name
     */
    protected String getAcceptableUsagePolicyColumnName(final JdbcAcceptableUsagePolicyProperties jdbc) {
        return StringUtils.defaultIfBlank(jdbc.getAupColumn(), aupProperties.getCore().getAupAttributeName()).trim();
    }

    /**
     * Extracts principal ID from a principal attribute or the provided credentials.
     *
     * @param principal the principal
     * @return the principal ID to update the AUP setting in the database for
     */
    protected String determinePrincipalId(final Principal principal) {
        if (StringUtils.isBlank(aupProperties.getJdbc().getPrincipalIdAttribute())) {
            return principal.getId();
        }
        val pIdAttribName = aupProperties.getJdbc().getPrincipalIdAttribute();
        if (!principal.getAttributes().containsKey(pIdAttribName)) {
            throw new IllegalStateException("Principal attribute [" + pIdAttribName + "] cannot be found");
        }
        val pIdAttributeValue = principal.getAttributes().get(pIdAttribName);
        val pIdAttributeValues = CollectionUtils.toCollection(pIdAttributeValue);
        var principalId = StringUtils.EMPTY;
        if (!pIdAttributeValues.isEmpty()) {
            principalId = pIdAttributeValues.iterator().next().toString().trim();
        }
        if (pIdAttributeValues.size() > 1) {
            LOGGER.warn("Principal attribute [{}] was found, but its value [{}] is multi-valued. "
                        + "Proceeding with the first element [{}]", pIdAttribName, pIdAttributeValue, principalId);
        }
        if (principalId.isEmpty()) {
            throw new IllegalStateException("Principal attribute [" + pIdAttribName + "] was found, but it is either empty"
                                            + " or multi-valued with an empty element");
        }
        return principalId;
    }
}

View on GitHub (pinned to e7288fc434)