apereo/cas · warning
No custom principal attribute was provided by the client
Error message
No custom principal attribute was provided by the client [{}]. Using the default id [{}] What it means
BaseDelegatedClientAuthenticationHandler.determinePrincipalIdFrom logs this warning when the pac4j client reports a custom principal attribute type (principalAttribute set on the client/profile), yet the client did not actually supply that attribute, so CAS falls back to the profile's default identifier. Authentication still succeeds; only the principal-id source differs from the requested one.
Solutions
- Configure the provider to release the expected attribute (scopes/claims/attribute-release policy).
- Fix the client's principal attribute name so it matches an attribute present in the profile.
- Accept the default id and silence the warning by removing the client principal-attribute configuration if the default typed id is acceptable.
Example fix
// before (client config requesting an attribute the IdP never sends)
client.setPrincipalAttribute("sub"); // sub not in profile
// after
client.setPrincipalAttribute("email"); // email present in profile Defensive patterns
Strategy: validation
Validate before calling
if (StringUtils.isNotBlank(clientPrincipalAttribute) && !profile.containsAttribute(clientPrincipalAttribute)) {
// request the attribute via provider scopes or correct the name
} Prevention
- Match client principalAttribute names against actually-released profile attributes.
- Request required claims/scopes from the IdP in client configuration.
When it happens
Trigger: The pac4j client's principal attribute is configured (client's principalAttribute non-blank) but the returned profile lacks the attribute value (the else branch when firstAttribute/attribute is absent), during determinePrincipalIdFrom called via extractedCredential in delegated client authentication.
Common situations: Provider not releasing the configured client principal attribute; misconfigured client-level principal attribute name; providers returning thin profiles (e.g. implicit flow with minimal claims).
Related errors
- Authentication cannot find attribute
- CAS cannot use [ ] as the principal attribute id, since the…
- Delegated authentication has failed with client
- Client name for [ ] is set to a generated value of [ ]…
- Service access for [ ] is denied
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/c814f1fc02daee6f.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-pac4j-core-clients/src/main/java/org/apereo/cas/support/pac4j/authentication/handler/support/BaseDelegatedClientAuthenticationHandler.java:122
protected String determinePrincipalIdFrom(final UserProfile profile, final BaseClient client) {
var id = profile.getId();
val properties = client != null ? client.getCustomProperties() : new HashMap<>();
if (client != null && properties.containsKey(ClientCustomPropertyConstants.CLIENT_CUSTOM_PROPERTY_PRINCIPAL_ATTRIBUTE_ID)) {
val attrObject = properties.get(ClientCustomPropertyConstants.CLIENT_CUSTOM_PROPERTY_PRINCIPAL_ATTRIBUTE_ID);
if (attrObject != null) {
val principalAttribute = attrObject.toString();
if (profile.containsAttribute(principalAttribute)) {
val firstAttribute = CollectionUtils.firstElement(profile.getAttribute(principalAttribute));
if (firstAttribute.isPresent()) {
id = firstAttribute.get().toString();
id = typePrincipalId(id, profile);
}
LOGGER.debug("Authentication indicates usage of client principal attribute [{}] for the identifier [{}]", principalAttribute, id);
} else {
LOGGER.warn("Authentication cannot find attribute [{}] to use as principal id", principalAttribute);
}
} else {
LOGGER.warn("No custom principal attribute was provided by the client [{}]. Using the default id [{}]", client, id);
}
} else if (StringUtils.isNotBlank(principalAttributeId)) {
if (profile.containsAttribute(principalAttributeId)) {
val firstAttribute = CollectionUtils.firstElement(profile.getAttribute(principalAttributeId));
if (firstAttribute.isPresent()) {
id = firstAttribute.get().toString();
id = typePrincipalId(id, profile);
}
} else {
LOGGER.warn("CAS cannot use [{}] as the principal attribute id, since the profile attributes do not contain the attribute. "
+ "Either adjust the CAS configuration to use a different attribute, or contact the authentication provider noted by [{}] "
+ "to release the expected attribute to CAS", principalAttributeId, profile.getAttributes());
}
LOGGER.debug("Authentication indicates usage of attribute [{}] for the identifier [{}]", principalAttributeId, id);
} else if (isTypedIdUsed) {
id = profile.getTypedId();
LOGGER.debug("Authentication indicates usage of typed profile id [{}]", id);
}View on GitHub (pinned to e7288fc434)