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

  1. Run the authentication manager and collect its result before calling build().
  2. Check earlier flow steps for swallowed exceptions that skipped authentication collection.
  3. Guard custom code against a null return from build() when authentications may be empty.
  4. 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

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.

Related errors


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)