apereo/cas · warning

Could not find value for mapped attribute

Error message

Could not find value for mapped attribute [{}] that is based off of [{}] in the allowed attributes list. Ensure the original attribute [{}] is retrieved and contains at least a single value. Attribute [{}] will and can not be released without the presence of a value.

What it means

WS-Federation claims release policy maps requested claim URIs (e.g. emailaddress) to CAS attribute names; when the mapped source attribute is absent or has no value in the principal's attribute bundle, the claim cannot be released and this warning is logged. Release proceeds without that attribute.

Solutions

  1. Ensure the authentication/attribute source actually retrieves the mapped attribute (e.g. add it to LDAP allowed attributes)
  2. Fix the mapping in the WS-Federation service's claims mapping so it points at an attribute the principal really has
  3. Check attribute casing/naming against what the principal carries and align
  4. If the claim is genuinely optional, ignore the warning; it only means the claim is skipped

Example fix

// before: mapping claims to 'mail' but only 'email' is fetched
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -> "mail"
// after: align with retrieved attribute name
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -> "email"
Defensive patterns

Strategy: validation

Validate before calling

var missing = claimsMap.values().stream().filter(a -> principal.getAttributes().get(a) == null).toList();
if (!missing.isEmpty()) LOGGER.warn("Attributes missing for claims: {}", missing);

Prevention

When it happens

Trigger: mapSingleAttributeDefinition -> mapSimpleSingleAttributeDefinition is called during attribute release and allowedAttributes.get(mappedAttributeName) returns null because the principal lacks the attribute the claim maps to.

Common situations: LDAP/attribute repository not returning the mapped attribute (no mail, givenName, etc.); claim-to-attribute mapping names an attribute with different casing; user record missing the value; attribute filtered out by an earlier release/filter policy.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-ws-idp-api/src/main/java/org/apereo/cas/ws/idp/services/WSFederationClaimsReleasePolicy.java:79

                    LOGGER.trace("Evaluating claim [{}] mapped to attribute value [{}]", claim.getUri(), attributeValue);
                    mapSingleAttributeDefinition(claim.getUri(), entry.getValue(),
                        attributeValue, resolvedAttributes, attributesToRelease);
                }
            });
        return attributesToRelease;
    }

    private static void mapSimpleSingleAttributeDefinition(final String attributeName,
                                                           final String mappedAttributeName,
                                                           final List<Object> attributeValue,
                                                           final Map<String, List<Object>> attributesToRelease) {
        if (attributeValue != null) {
            LOGGER.debug("Found attribute [{}] in the list of allowed attributes, mapped to the name [{}]",
                attributeName, mappedAttributeName);
            val values = CollectionUtils.toCollection(attributeValue, ArrayList.class);
            attributesToRelease.put(attributeName, values);
        } else {
            LOGGER.warn("Could not find value for mapped attribute [{}] that is based off of [{}] in the allowed attributes list. "
                    + "Ensure the original attribute [{}] is retrieved and contains at least a single value. Attribute [{}] "
                    + "will and can not be released without the presence of a value.", mappedAttributeName, attributeName,
                attributeName, mappedAttributeName);
        }
    }

    private static void mapSingleAttributeDefinition(final String attributeName,
                                                     final String mappedAttributeName,
                                                     final List<Object> attributeValue,
                                                     final Map<String, List<Object>> resolvedAttributes,
                                                     final Map<String, List<Object>> attributesToRelease) {
        val scriptFactoryInstance = ExecutableCompiledScriptFactory.findExecutableCompiledScriptFactory();

        if (scriptFactoryInstance.isPresent()) {
            val scriptFactory = scriptFactoryInstance.get();
            
            if (scriptFactory.isInlineScript(mappedAttributeName)) {
                val inlineGroovy = scriptFactory.getInlineScript(mappedAttributeName).orElseThrow();

View on GitHub (pinned to e7288fc434)