apereo/cas · warning
Principal resolution handled by
Error message
Principal resolution handled by [{}] produced a null principal for: [{}]CAS is configured to treat principal resolution failures as fatal. What it means
When principal resolution yields a null principal and cas.authn.principalResolutionFailureFatal is true, DefaultAuthenticationManager.authenticateAndResolvePrincipal logs this warning and throws UnresolvedPrincipalException, aborting authentication. CAS is configured to treat a failed resolution as fatal rather than falling back to the handler's principal.
Solutions
- Verify the underlying attribute repository (LDAP/JDBC/etc.) has a record for the resolved user.
- Set cas.authn.principalResolutionFailureFatal=false to fall back to the handler-produced principal (only if acceptable).
- Fix resolver configuration so it supports the credential (see error 360).
- Inspect the preceding ERROR log line '[resolver] failed to resolve principal' for the root cause exception.
Example fix
// before cas.authn.principal-resolution-failure-fatal=true // after (allow fallback to handler principal) cas.authn.principal-resolution-failure-fatal=false
Defensive patterns
Strategy: try-catch
Validate before calling
val resolved = principalResolver.resolve(credential);
if (resolved == null) {
// fix attribute source before enabling fatal mode
} Try / catch
try {
authenticationManager.authenticate(transaction);
} catch (UnresolvedPrincipalException e) {
LOGGER.error("Principal resolution failed for {}", transaction.getCredentials(), e);
// present a user-friendly failure or repair attribute repository
} Prevention
- Monitor attribute repository health; fatal principal resolution turns an LDAP outage into a total login outage.
- Only set principalResolutionFailureFatal=true when attributes are strictly required.
When it happens
Trigger: principalResolutionFailureFatal=true and resolvePrincipal (or the handler result itself) returns null — e.g. resolver unsupported credential (see [360]), empty attribute repository result, or handler produced no principal.
Common situations: Strict deployments where principal MUST come from the attribute source (LDAP/JDBC) but the attribute repository is down or the user record is missing; misconfigured resolver so resolution silently fails; principal mapping/removal of attributes results in null.
Related errors
- Unable to detect the authentication principal for
- [ ] is configured to use [ ] but it does not support [ ]…
- Principal resolution handled by
- Authentication handler is disabled
- No user can be accepted because none is defined
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/c5ea4933f6c493e5.
Report an issue: GitHub.
Appendix: source
Thrown at core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/DefaultAuthenticationManager.java:169
final AuthenticationHandler handler,
final Service service) throws Throwable {
val clientInfo = ClientInfoHolder.getClientInfo();
publishEvent(new CasAuthenticationTransactionStartedEvent(this, credential, clientInfo));
try {
AuthenticationHolder.setCurrentAuthentication(authenticationBuilder.build());
val handlerExecutionResult = handler.authenticate(credential, service);
val authenticationHandlerName = handler.getName();
authenticationBuilder.addSuccess(authenticationHandlerName, handlerExecutionResult);
LOGGER.debug("Authentication handler [{}] successfully authenticated [{}]", authenticationHandlerName, credential);
publishEvent(new CasAuthenticationTransactionSuccessfulEvent(this, credential, clientInfo));
var principal = principalResolver != null
? resolvePrincipal(handler, principalResolver, credential, handlerExecutionResult.getPrincipal(), service)
: handlerExecutionResult.getPrincipal();
if (principal == null) {
val resolverName = principalResolver == null ? authenticationHandlerName : principalResolver.getName();
if (this.principalResolutionFailureFatal) {
LOGGER.warn("Principal resolution handled by [{}] produced a null principal for: [{}]"
+ "CAS is configured to treat principal resolution failures as fatal.", resolverName, credential);
throw new UnresolvedPrincipalException();
}
LOGGER.warn("Principal resolution handled by [{}] produced a null principal. "
+ "This is likely due to misconfiguration or missing attributes; CAS will attempt to use the principal "
+ "produced by the authentication handler, if any.", resolverName);
} else {
val currentPrincipal = authenticationBuilder.getPrincipal();
if (!(currentPrincipal instanceof NullPrincipal)) {
val merger = authenticationSystemSupport.getObject().getPrincipalElectionStrategy().getAttributeMerger();
LOGGER.trace("Merging attributes from [{}] into principal [{}]", principal, currentPrincipal);
val mergedAttributes = CoreAuthenticationUtils.mergeAttributes(currentPrincipal.getAttributes(), principal.getAttributes(), merger);
principal = principal.withAttributes(mergedAttributes);
LOGGER.debug("Merged attributes into principal [{}]", principal);
}
authenticationBuilder.setPrincipal(principal);
}
LOGGER.debug("Final principal resolved for this authentication event is [{}]", principal);View on GitHub (pinned to e7288fc434)