apereo/cas · error · FailedLoginException

Authentication did not produce a user profile for:

Error message

Authentication did not produce a user profile for: 

What it means

BaseDelegatedClientAuthenticationHandler.createResult throws FailedLoginException when the delegated (pac4j) client authentication returned a null UserProfile. Without a profile there is no user to build an AuthenticationHandlerExecutionResult from.

Solutions

  1. Check CAS logs for the underlying pac4j client errors before this handler to find why the profile is null
  2. Verify the delegated client configuration (client ID/secret, callback URL) with the identity provider
  3. Reproduce the IdP callback manually and confirm it returns a profile the pac4j client can extract

Example fix

// before
cas.authn.pac4j.oidc[0].generic.client-id=<wrong>
cas.authn.pac4j.oidc[0].generic.discovery-uri=https://bad-idp.example.org/.well-known/openid-configuration
// after
cas.authn.pac4j.oidc[0].generic.client-id=real-client-id
cas.authn.pac4j.oidc[0].generic.discovery-uri=https://real-idp.example.org/.well-known/openid-configuration
Defensive patterns

Strategy: try-catch

Validate before calling

if (profile == null) { failFast("no profile from IdP callback"); }

Try / catch

try { result = handler.createResult(credentials, profile, client, service); }
catch (FailedLoginException e) { redirect to error page and inspect pac4j logs for the IdP failure; }

Prevention

When it happens

Trigger: A callback from the delegated identity provider reaches createResult with profile == null — e.g. the IdP response lacked the data pac4j needs, the client's profile extractor failed silently, or the callback was forged/invalid so no session profile could be restored.

Common situations: Misconfigured delegated client (bad callback URL/credentials) causing the IdP to return an error page instead of profile data; IdP protocol version changes breaking profile extraction; users hitting the callback endpoint directly without completing the flow.

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/de323fe91a51940e. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-pac4j-core-clients/src/main/java/org/apereo/cas/support/pac4j/authentication/handler/support/BaseDelegatedClientAuthenticationHandler.java:55

    protected final SessionStore sessionStore;

    protected String principalAttributeId;

    protected boolean isTypedIdUsed;

    protected BaseDelegatedClientAuthenticationHandler(final String name,
                                                       final PrincipalFactory principalFactory, final Integer order,
                                                       final SessionStore sessionStore) {
        super(name, principalFactory, order);
        this.sessionStore = sessionStore;
    }

    protected AuthenticationHandlerExecutionResult createResult(final ClientCredential credentials,
                                                                final UserProfile profile,
                                                                final BaseClient client,
                                                                final Service service) throws Throwable {
        if (profile == null) {
            throw new FailedLoginException("Authentication did not produce a user profile for: " + credentials);
        }

        val extractedCredential = new BasicIdentifiableCredential(determinePrincipalIdFrom(profile, client));
        val id = transformUsername(extractedCredential);
        if (StringUtils.isBlank(id)) {
            throw new FailedLoginException("No identifier found for this user profile: " + profile);
        }
        credentials.setUserProfile(profile);
        credentials.setTypedIdUsed(isTypedIdUsed);
        val attributes = CollectionUtils.toMultiValuedMap(profile.getAttributes());
        attributes.put(Pac4jConstants.CLIENT_NAME, CollectionUtils.wrap(profile.getClientName()));
        if (profile instanceof final BasicUserProfile bup) {
            attributes.putAll(CollectionUtils.toMultiValuedMap(bup.getAuthenticationAttributes()));
        }
        val initialPrincipal = Objects.requireNonNull(principalFactory.createPrincipal(id, attributes));
        val principal = finalizeAuthenticationPrincipal(initialPrincipal, client, credentials, service);
        LOGGER.debug("Constructed authenticated principal [{}] based on user profile [{}]", principal, profile);
        return finalizeAuthenticationHandlerResult(credentials, principal, profile, client, service);

View on GitHub (pinned to e7288fc434)