apereo/cas · warning
Provided authentication result is undefined to evaluate for…
Error message
Provided authentication result is undefined to evaluate for mixed principals
What it means
evaluatePossibilityOfMixedPrincipals in DefaultCentralAuthenticationService warns and returns null when a null AuthenticationResult is supplied while comparing the TGT's principal with a new authentication result. It guards the mixed-principal detection during TGT re-establishment; null means the check could not be performed, so the caller treats it as 'no mixed principal detected'.
Solutions
- Ensure an AuthenticationResult is built and passed whenever a TGT is presented for re-evaluation
- Check the authentication handler chain: a failed/aborted authentication produces a null result — fix the underlying authentication failure first
- If the null result is intentional (pure SSO re-use), treat the warn as benign and confirm mixed-principal policy tolerates it
- Review custom CentralAuthenticationService call sites for paths that skip authentication result creation
Example fix
// before acs.grantTicketGrantingTicket(tgtId, null); // after val result = authenticationResultBuilder.build(fixedCredentials, service); acs.grantTicketGrantingTicket(tgtId, result);
Defensive patterns
Strategy: validation
Validate before calling
if (authenticationResult == null) {
throw new IllegalArgumentException("AuthenticationResult required when a TGT is presented");
} Type guard
boolean canEvaluate = context != null && context.getAuthentication() != null && ticketGrantingTicket.getAuthentication() != null;
Prevention
- Always build an AuthenticationResult before granting a TGT
- Do not call grantServiceTicket/grantTicketGrantingTicket with null results on SSO re-use paths
- Audit custom protocol handlers for null AuthenticationResult paths
When it happens
Trigger: Calling grantTicketGrantingTicket/evaluatePossibilityOfMixedPrincipals (via CentralAuthenticationService flows) with a null AuthenticationResult context alongside an existing TicketGrantingTicket — e.g. an SSO session refresh where no fresh authentication result was built.
Common situations: Custom authentication flows or protocol handlers (SAML/OIDC delegating flows) that re-use a TGT without producing a new AuthenticationResult; misconfigured service ticket grant flows that pass a null result after a failed authentication attempt.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Denied
- No identifier found for this user profile:
- Authentication handler is disabled
- No user can be accepted because none is defined
- not found in backing map.
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/565d1eabcb27fdea.
Report an issue: GitHub.
Appendix: source
Thrown at core/cas-server-core/src/main/java/org/apereo/cas/DefaultCentralAuthenticationService.java:409
.build();
enforceRegisteredServiceAccess(audit);
}
protected @Nullable Principal rebuildStatelessTicketPrincipal(final ServiceTicket serviceTicket) throws Throwable {
val authentication = serviceTicket.getAuthentication();
return configurationContext.getPrincipalResolver()
.resolve(new BasicIdentifiableCredential(
Objects.requireNonNull(authentication).getPrincipal().getId()),
Optional.of(authentication.getPrincipal()), Optional.empty(),
Optional.of(serviceTicket.getService()));
}
private static @Nullable Authentication evaluatePossibilityOfMixedPrincipals(
@Nullable final AuthenticationResult context,
final TicketGrantingTicket ticketGrantingTicket) {
if (context == null) {
val error = "Provided authentication result is undefined to evaluate for mixed principals";
LOGGER.warn(error);
return null;
}
val currentAuthentication = context.getAuthentication();
if (currentAuthentication != null) {
val original = ticketGrantingTicket.getAuthentication();
if (!currentAuthentication.getPrincipal().equals(Objects.requireNonNull(original).getPrincipal())) {
throw new MixedPrincipalException(currentAuthentication,
currentAuthentication.getPrincipal(), original.getPrincipal());
}
}
return currentAuthentication;
}
@RequiredArgsConstructor
private final class ServiceTicketGrantor implements CheckedSupplier<Ticket> {
private final String ticketGrantingTicketId;
private final Service service;
private final @Nullable AuthenticationResult authenticationResult;View on GitHub (pinned to e7288fc434)