apereo/cas · error
Google authenticator token credential is not assigned a…
Error message
Google authenticator token credential is not assigned a valid account id
What it means
During the Google Authenticator validate-selected-registration webflow step, CAS loads the registration account matching the request but the submitted token credential carries a null accountId or one that does not equal the located account's id. This is a cross-check that the credential being validated actually belongs to the registration the user selected. On mismatch the action logs a warning, adds an error message to the flow context, and returns an error outcome.
Solutions
- Ensure the client-side registration form submits the correct hidden accountId field for the selected device
- Reconstruct the credential from current request parameters so accountId is populated from the same registration the user selected
- Verify the account lookup resolves the registration matching the credential's accountId
- Clear stale browser session/form state and retry the registration-validation flow
Example fix
// before
class GoogleAuthenticatorTokenCredential { private Long accountId; /* never set */ }
// after
class GoogleAuthenticatorTokenCredential {
GoogleAuthenticatorTokenCredential(String token, Long accountId) {
this.token = token;
this.accountId = Objects.requireNonNull(accountId, "accountId required");
}
} Defensive patterns
Strategy: validation
Validate before calling
if (credential.getAccountId() == null || !credential.getAccountId().equals(account.getId())) {
throw new IllegalStateException("Credential accountId missing/mismatch for registration " + account.getId());
} Type guard
boolean hasValidAccountId(var c) { return c.getAccountId() != null && c.getAccountId() > 0; } Prevention
- Always set accountId on the token credential at construction time from the same form field as the token
- Keep the selected-registration id in the webflow scope and bind it to the credential server-side
- Include the accountId as a required hidden field in the registration form
When it happens
Trigger: Credential built by the client/registration flow with accountId left unset, or the credential's accountId refers to a different registration than the one resolved for the current principal (e.g. stale form data, multiple devices registered, tampered request).
Common situations: User has multiple registered GAuth devices and the browser posted a stale form; custom client code constructs GoogleAuthenticatorTokenCredential without calling setAccountId; session/form data from a previous registration is replayed.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Failed to authenticate code
- Unauthorized account registration attempt for id
- Failed to authenticate code
- Unauthorized account removal attempt
- Failed to authenticate code
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/3cd8bd095781e3c9.
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:53
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)