apereo/cas · warning
Credential attributes do not include an attribute for
Error message
Credential attributes do not include an attribute for [{}]. This will prohibit CAS to construct a meaningful authenticated principal. Examine the released claims and ensure [{}] is allowed What it means
WsFederationCredentialsToPrincipalResolver could not build a principal id because the credential's attributes do not contain the configured principal id attribute (the WS-Federation claim). CAS logs this warning and returns null, meaning no meaningful authenticated principal can be constructed from the WS-Federation response. It typically indicates the ADFS/AD FS relying-party claim rules do not release the required claim to CAS.
Solutions
- On the ADFS/STS server, add an issuance authorization/transform rule that releases the required claim (e.g. Name ID or LDAP attribute mapped to the expected claim) to the CAS relying-party trust.
- Check the cas.authn.wsfed principal-attribute configuration value and make sure it exactly matches a claim released in the WS-Federation response (inspect the released claims in debug logs).
- If the claim is intentionally unavailable, change the principal attribute to one that is always released, or set principal-attribute to NameID-style default so the default principal id is used.
- Enable debug logging for WsFederationCredentialsToPrincipalResolver to see which claims are actually present on the credential and correct the mapping.
Example fix
// before (application.properties) cas.authn.wsfed.principal.principal-attribute=email // after (claim actually released by the IdP) cas.authn.wsfed.principal.principal-attribute=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn
Defensive patterns
Strategy: validation
Validate before calling
// Before relying on WS-FED principal resolution, verify the claim is released:
val attrs = credential.getAttributes();
if (!attrs.containsKey(principalAttributeName)) {
logger.warn("Claim [{}] not released by IdP; fix ADFS issuance rules", principalAttributeName);
}
return attrs.containsKey(principalAttributeName); Try / catch
try {
val principal = resolver.resolve(credentials, ...);
if (principal == null || principal.getId() == null) {
// treat as failed resolution, fall back to alternate attribute or reject
}
} catch (PrincipalResolutionException e) {
logger.error("WS-FED principal resolution failed", e);
} Prevention
- Keep ADFS issuance rules documented alongside CAS wsfed principal-attribute settings so they stay in sync.
- Log released claims at debug level during initial SSO integration testing.
- Use exact claim URIs (not short names) when configuring principal attributes.
- Add a startup/config test that authenticates a test user and asserts the principal attribute exists.
When it happens
Trigger: extractPrincipalId is called after extracting WS-Federation credential attributes; the configured principal id attribute name (e.g. a claim like NameID, UPN, or a custom attribute) is absent from the credential's attribute map, so the resolver lookup returns empty and this warn path is hit.
Common situations: ADFS/STS issuing organization not releasing the claim CAS is configured to use as the principal attribute; mismatch between cas.authn.wsfed.principal.principal-attribute value and the actual claim name (case/space differences); certificate/key-dependent claim transformation not applied for the CAS relying party trust.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unable to determine the [WA] parameter
- No state could be found to determine session state
- Found multiple values for id attribute
- Denied
- JWT time claim is invalid
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/127802be79d3952b.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-wsfederation/src/main/java/org/apereo/cas/support/wsfederation/authentication/principal/WsFederationCredentialsToPrincipalResolver.java:57
LOGGER.debug("Credential attributes provided are: [{}]", attributes);
val idAttribute = configuration.getIdentityAttribute();
if (attributes.containsKey(idAttribute)) {
LOGGER.debug("Extracting principal id from attribute [{}]", this.configuration.getIdentityAttribute());
val idAttributeAsList = CollectionUtils.toCollection(attributes.get(this.configuration.getIdentityAttribute()));
if (idAttributeAsList.size() > 1) {
LOGGER.warn("Found multiple values for id attribute [{}].", idAttribute);
} else {
LOGGER.debug("Found principal id attribute as [{}]", idAttributeAsList);
}
val result = CollectionUtils.firstElement(idAttributeAsList);
if (result.isPresent()) {
val principalId = result.get().toString();
LOGGER.debug("Principal Id extracted from credentials: [{}]", principalId);
return principalId;
}
}
LOGGER.warn("Credential attributes do not include an attribute for [{}]. "
+ "This will prohibit CAS to construct a meaningful authenticated principal. "
+ "Examine the released claims and ensure [{}] is allowed", idAttribute, idAttribute);
return null;
}
@Override
protected Map<String, List<Object>> retrievePersonAttributes(final String principalId,
final Credential credential,
final Optional<Principal> currentPrincipal,
final Map<String, List<Object>> queryAttributes,
final Optional<Service> service,
final Optional<AuthenticationHandler> handler) throws Throwable {
val wsFedCredentials = (WsFederationCredential) credential;
if (this.configuration.getAttributesType() == WsFederationConfiguration.WsFedPrincipalResolutionAttributesType.WSFED) {
return wsFedCredentials.getAttributes();
}
if (this.configuration.getAttributesType() == WsFederationConfiguration.WsFedPrincipalResolutionAttributesType.CAS) {
return super.retrievePersonAttributes(principalId, credential, currentPrincipal, new HashMap<>(), service, handler);View on GitHub (pinned to e7288fc434)