apereo/cas · warning

Principal resolution is unable to produce a result and will…

Error message

Principal resolution is unable to produce a result and will return null

What it means

PersonDirectoryPrincipalResolver.resolve could not build a valid principal from the retrieved attributes; because returnNullIfNoAttributes is enabled, it logs this warning and returns null instead of throwing, meaning the credential will not be associated with a resolved principal.

Solutions

  1. Set cas.authn.attribute-repository.return-null-if-no-attributes=false if a principal without attributes is acceptable
  2. Verify the attribute repository (LDAP/JDBC/JSON) returns attributes for this user
  3. Check the principal attribute mapping/attribute names in cas.authn.attribute-repository.* configuration
  4. Enable debug logging to see the principalId and retrieved attribute count before conversion

Example fix

// before
cas.authn.attribute-repository.return-null-if-no-attributes=true
// after
cas.authn.attribute-repository.return-null-if-no-attributes=false
Defensive patterns

Strategy: fallback

Validate before calling

if (attributes.isEmpty()) { LOGGER.warn("No attributes for {}", principalId); }

Try / catch

Principal p = resolver.resolve(cred, Optional.of(ctx)); if (p == null) { use fallback principal or fail with clear message; }

Prevention

When it happens

Trigger: convertPersonAttributesToPrincipal fails to produce a successful result (no usable principal id/attributes) and the resolver's returnNullIfNoAttributes flag is true during resolve().

Common situations: Attribute repository returns no attributes for the principal id; attribute mapping misconfigured so required attributes are missing; caching/screens configuration excludes attributes; principal id attribute resolves to blank.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-person-directory-core/src/main/java/org/apereo/cas/authentication/principal/resolvers/PersonDirectoryPrincipalResolver.java:90

        }
        LOGGER.trace("Creating principal for [{}]", principalId);
        if (context.isResolveAttributes()) {
            val attributes = retrievePersonAttributes(principalId, credential,
                currentPrincipal, new HashMap<>(), service, handler);
            if (attributes == null || attributes.isEmpty()) {
                LOGGER.debug("Principal id [{}] did not specify any attributes", principalId);
                if (!context.isReturnNullIfNoAttributes()) {
                    val principal = buildResolvedPrincipal(principalId, new HashMap<>(), credential, currentPrincipal, handler);
                    LOGGER.debug("Returning the principal with id [{}] without any attributes", principal);
                    return principal;
                }
                LOGGER.debug("[{}] is configured to return null if no attributes are found for [{}]", getClass().getName(), principalId);
                return null;
            }
            LOGGER.debug("Retrieved [{}] attribute(s) from the repository", attributes.size());
            val result = convertPersonAttributesToPrincipal(principalId, currentPrincipal, attributes);
            if (!result.isSuccess() && context.isReturnNullIfNoAttributes()) {
                LOGGER.warn("Principal resolution is unable to produce a result and will return null");
                return null;
            }

            val principal = buildResolvedPrincipal(result.getPrincipalId(), result.getAttributes(),
                credential, currentPrincipal, handler);
            LOGGER.debug("Final resolved principal by [{}] is [{}]", getName(), principal);
            return principal;
        }
        val principal = buildResolvedPrincipal(principalId, new HashMap<>(),
            credential, currentPrincipal, handler);
        LOGGER.debug("Final resolved principal by [{}] without resolving attributes is [{}]", getName(), principal);
        return principal;
    }

    @Override
    public boolean supports(final Credential credential) {
        return credential != null && credential.getId() != null;
    }

View on GitHub (pinned to e7288fc434)