apereo/cas · warning

No surrogate identifier was selected or provided

Error message

No surrogate identifier was selected or provided

What it means

SurrogateSelectionAction finalizes the webflow surrogate-selection step. If the credential is a supported (username/password) credential but no surrogate target identifier was supplied (form field, request parameter, or previously selected value), it logs this warning and continues with just the primary identity - the user proceeds as themselves without impersonation. It signals the selection step was skipped or the UI failed to submit a choice.

Solutions

  1. Ensure the login form for surrogate-enabled services includes and submits the surrogate selection field.
  2. Verify the custom theme/webflow passes the surrogate identifier parameter through to the action.
  3. If self-login is intended, ignore the warning or disable surrogate for that service to stop the selection prompt.
  4. Test the selection page flow end-to-end after any webflow customization.

Example fix

<!-- before: form missing surrogate input -->
<input type="text" name="username"/>
<!-- after -->
<input type="text" name="username"/>
<input type="text" name="surrogateTarget" placeholder="impersonate user"/>
Defensive patterns

Strategy: validation

Validate before calling

String surrogateTarget = requestContext.getRequestParameters().get("surrogateTarget");
if (surrogateTarget == null || surrogateTarget.isBlank()) {
    // render selection page or proceed as primary user deliberately
}

Prevention

When it happens

Trigger: doExecuteInternal finds a supported credential, but the surrogate target request parameter / selected identifier is blank after evaluation, so the branch that adds SurrogateCredentialTrait and builds the surrogate authentication result never runs.

Common situations: Theme/page does not render or submit the surrogate selection input; user leaves the selector empty expecting self-login; custom webflow modifications dropped the surrogateSelection parameter; direct POST to login bypassing the selection page.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/a2d3f351202d17fa. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-surrogate-webflow/src/main/java/org/apereo/cas/web/flow/action/SurrogateSelectionAction.java:59

    @Override
    protected @Nullable Event doExecuteInternal(final RequestContext requestContext) {
        val resultMap = new HashMap<String, Object>();
        try {
            val credential = WebUtils.getCredential(requestContext);
            if (credential instanceof final MutableCredential mc) {
                val surrogateTarget = WebUtils.getRequestParameterOrAttribute(requestContext, PARAMETER_NAME_SURROGATE_TARGET)
                    .orElse(StringUtils.EMPTY);
                LOGGER.debug("Located surrogate target as [{}]", surrogateTarget);

                if (StringUtils.isNotBlank(surrogateTarget)) {
                    resultMap.put(PARAMETER_NAME_SURROGATE_TARGET, surrogateTarget);
                    val registeredService = WebUtils.getRegisteredService(requestContext);
                    val builder = WebUtils.getAuthenticationResultBuilder(requestContext);
                    mc.getCredentialMetadata().addTrait(new SurrogateCredentialTrait(surrogateTarget));
                    val result = surrogatePrincipalBuilder.buildSurrogateAuthenticationResult(builder, mc, registeredService);
                    result.ifPresent(bldr -> WebUtils.putAuthenticationResultBuilder(bldr, requestContext));
                } else {
                    LOGGER.warn("No surrogate identifier was selected or provided");
                }
                resultMap.put("primary", credential.getId());
            } else {
                LOGGER.debug("Credential is not supported [{}]", credential);
            }
            return success(resultMap);
        } catch (final Throwable e) {
            WebUtils.addErrorMessageToContext(requestContext, "screen.surrogates.account.selection.error",
                "Unable to accept or authorize selection");
            LoggingUtils.error(LOGGER, e);
            return error(new RuntimeException(e));
        }
    }
}

View on GitHub (pinned to e7288fc434)