apereo/cas · warning
No authentication event has been recorded; CAS cannot…
Error message
No authentication event has been recorded; CAS cannot finalize the authentication result
What it means
In DefaultAuthenticationResultBuilder.buildAuthentication, if no authentication events were recorded at all, CAS logs this warning and returns null instead of fabricating an Authentication. Downstream this surfaces as a null authentication result when finalizing the flow.
Solutions
- Run the authentication manager and collect its result before calling build().
- Check earlier flow steps for swallowed exceptions that skipped authentication collection.
- Guard custom code against a null return from build() when authentications may be empty.
- In tests, seed the builder with at least one Authentication.
Example fix
// before val result = resultBuilder.build(principalElectionStrategy); // null // after val authentication = authenticationManager.authenticate(transaction); resultBuilder.collect(authentication); val result = resultBuilder.build(principalElectionStrategy);
Defensive patterns
Strategy: try-catch
Validate before calling
if (resultBuilder.isEmpty() /* or authentications not collected */) {
throw new IllegalStateException("Cannot build result: no authentications collected");
} Type guard
Authentication auth = resultBuilder.build(principalElectionStrategy);
if (auth == null) {
// rerun authentication manager before finalizing
} Try / catch
try {
val result = resultBuilder.build(strategy);
if (result == null) {
LOGGER.error("Authentication result is null — no authentications recorded");
}
} catch (Throwable e) {
LOGGER.error("Failed to build authentication result", e);
} Prevention
- Never call build() on a freshly created builder in custom code or tests.
- Log and handle null results where the builder may legitimately be empty.
When it happens
Trigger: build(...) (via the authentication() method chain) invoked on a DefaultAuthenticationResultBuilder whose authentications list is empty — i.e. the authentication manager never ran or nothing was collected.
Common situations: Custom login flow bypassing the authentication manager; exception swallowed earlier so collection never happened; service/app integration calling build() on a freshly created builder in tests or extension code.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Authentication chain is empty as no authentications have…
- Provided credentials chain is empty as no credentials have…
- 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/43f10caa0f6c44bd.
Report an issue: GitHub.
Appendix: source
Thrown at core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/DefaultAuthenticationResultBuilder.java:141
authentications.forEach(authn -> {
mergePrincipalAttributes(principalAttributes, merger, authn);
mergeAuthenticationAttributes(authenticationAttributes, merger, authn);
authenticationBuilder
.addSuccesses(authn.getSuccesses())
.addFailures(authn.getFailures())
.addWarnings(authn.getWarnings())
.addCredentials(authn.getCredentials());
});
}
private boolean isEmpty() {
return this.authentications.isEmpty();
}
private @Nullable Authentication buildAuthentication(final PrincipalElectionStrategy principalElectionStrategy) throws Throwable {
if (isEmpty()) {
LOGGER.warn("No authentication event has been recorded; CAS cannot finalize the authentication result");
return null;
}
val authenticationAttributes = new HashMap<String, List<Object>>();
val principalAttributes = new HashMap<String, List<Object>>();
val authenticationBuilder = DefaultAuthenticationBuilder.newInstance();
buildAuthenticationHistory(this.authentications, authenticationAttributes,
principalAttributes, authenticationBuilder, principalElectionStrategy);
synchronized (this.authentications) {
val primaryPrincipal = getPrimaryPrincipal(principalElectionStrategy, this.authentications, principalAttributes);
authenticationBuilder.setPrincipal(primaryPrincipal);
}
LOGGER.debug("Determined primary authentication principal to be [{}]", authenticationBuilder.getPrincipal());
authenticationBuilder.setAttributes(authenticationAttributes);
LOGGER.trace("Collected authentication attributes for this result are [{}]", authenticationAttributes);
View on GitHub (pinned to e7288fc434)