apereo/cas · error

Unable to determine google authenticator account

Error message

Unable to determine google authenticator account

What it means

GoogleAuthenticatorValidateSelectedRegistrationAction retrieves the previously selected OneTimeTokenAccount from the webflow request context. When it is absent the action logs this warning, adds an error message, and returns error() so the MFA validation step cannot proceed.

Solutions

  1. Restart the MFA login flow and select a registered device before entering the token
  2. Check that the token repository actually contains an account for the user (registration completed and persisted)
  3. Avoid reusing stale webflow executions; start a fresh login attempt
  4. If customizing the flow, ensure the selection state stores the account into flow scope before this action runs
Defensive patterns

Strategy: fallback

Validate before calling

// before the validate-selected step, confirm an account is in scope
OneTimeTokenAccount acct =
    MultifactorAuthenticationWebflowUtils.getOneTimeTokenAccount(requestContext, OneTimeTokenAccount.class);
boolean ready = acct != null;

Try / catch

Event e = action.execute(requestContext);
if ("error".equals(e.getId())) {
    // route user back to device selection to repopulate the account
}

Prevention

When it happens

Trigger: doExecuteInternal runs but MultifactorAuthenticationWebflowUtils.getOneTimeTokenAccount(...) returns null: the user reached the validate-selected-registration state without having selected a registered device in the prior flow step (direct navigation, expired/lost flow scope, or repository lookup returned nothing).

Common situations: User bookmarks or re-submits the token entry page after the flow state expired; session loss between device-selection and token-entry steps; the selected registrationId no longer resolves (device deleted concurrently); custom flows skipping the selection state.

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

Appendix: source

Thrown at support/cas-server-support-gauth-core/src/main/java/org/apereo/cas/gauth/web/flow/GoogleAuthenticatorValidateSelectedRegistrationAction.java:41

@Slf4j
public class GoogleAuthenticatorValidateSelectedRegistrationAction extends BaseCasWebflowAction {
    private static final String CODE = "screen.authentication.gauth.invalid";

    private static void addErrorMessageToContext(final RequestContext requestContext) {
        WebUtils.addErrorMessageToContext(requestContext, CODE);
    }

    @Override
    protected @Nullable Event doExecuteInternal(final RequestContext requestContext) {
        if (MultifactorAuthenticationTrustUtils.isMultifactorAuthenticationTrustedInScope(requestContext)) {
            val trustedDevice = MultifactorAuthenticationTrustUtils.getMultifactorAuthenticationTrustRecord(requestContext, MultifactorAuthenticationTrustRecord.class).orElseThrow();
            LOGGER.info("Multifactor authentication device [{}] is trusted with fingerprint [{}]", trustedDevice.getName(), trustedDevice.getDeviceFingerprint());
            return success(trustedDevice);
        }

        val account = MultifactorAuthenticationWebflowUtils.getOneTimeTokenAccount(requestContext, OneTimeTokenAccount.class);
        if (account == null) {
            LOGGER.warn("Unable to determine google authenticator account");
            addErrorMessageToContext(requestContext);
            return error();
        }
        val credential = WebUtils.getCredential(requestContext, GoogleAuthenticatorTokenCredential.class);
        if (credential == null) {
            LOGGER.warn("Unable to determine google authenticator token credential");
            addErrorMessageToContext(requestContext);
            return error();
        }
        LOGGER.trace("Located account [{}] to be used for credential [{}]", account, credential);
        if (credential.getAccountId() == null || credential.getAccountId() != account.getId()) {
            LOGGER.warn("Google authenticator token credential is not assigned a valid account id");
            addErrorMessageToContext(requestContext);
            return error();
        }
        return null;
    }
}

View on GitHub (pinned to e7288fc434)