apereo/cas · error · FailedLoginException

No identifier found for this user profile:

Error message

No identifier found for this user profile: 

What it means

After obtaining a non-null UserProfile, createResult derives the principal id via determinePrincipalIdFrom, applies username transformation, and throws FailedLoginException when the resulting identifier is blank. A profile without a usable id cannot produce a CAS principal.

Solutions

  1. Inspect the UserProfile returned by the IdP (enable pac4j debug logs) to see why the id is empty
  2. Review the configured username transformation/attribute for the delegated client and fix or remove it
  3. Ensure the IdP reliably returns a subject/id for authenticated users

Example fix

// before
cas.authn.pac4j.core.username-attribute=nonexistentAttr // principal id resolves blank
// after
cas.authn.pac4j.core.username-attribute=email // attribute the IdP actually returns
Defensive patterns

Strategy: validation

Validate before calling

String id = profile != null ? profile.getId() : null;
if (id == null || id.isBlank()) { failFast("delegated profile has no identifier"); }

Prevention

When it happens

Trigger: Delegated authentication profile exists but determinePrincipalIdFrom returns null/empty and transformUsername yields blank — e.g. profile has no typed id, no id attribute, or a username transformation (regex/PrincipalTransformer) strips the entire identifier.

Common situations: Overly aggressive username transformation patterns removing the whole ID; IdP returning profiles with empty subject; attribute-based principal-id resolution configured to a missing attribute.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/ad31871926ab921a. 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:61

    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);
    }

    protected Principal finalizeAuthenticationPrincipal(final Principal initialPrincipal, final BaseClient client,
                                                        final ClientCredential credentials, final Service service) throws Throwable {
        return initialPrincipal;
    }

View on GitHub (pinned to e7288fc434)