apereo/cas · warning
Device registration is disabled for
Error message
Device registration is disabled for [{}] What it means
This is a warning logged by OneTimeTokenAccountSaveRegistrationAction.doExecuteInternal when a user attempts to save a new OTP device account while device registration is disabled in the MFA webflow configuration. The action short-circuits and returns the error event instead of registering the device. It is thrown when MultifactorAuthenticationWebflowUtils.isMultifactorDeviceRegistrationEnabled evaluates to false for the current request context.
Solutions
- Enable device registration in configuration (set cas.authn.mfa.device-registration-enabled=true or the equivalent feature toggle) if self-registration should be allowed.
- If registration should stay disabled, remove/hide the registration link and navigation to the OTP registration flow so users do not reach this action.
- Verify the request context/screen overrides (per-service or per-tenant MFA settings) are not unintentionally disabling registration for this user.
Example fix
// before: cas.properties cas.authn.mfa.device-registration-enabled=false // after cas.authn.mfa.device-registration-enabled=true
Defensive patterns
Strategy: validation
Validate before calling
boolean registrationEnabled = casProperties.getAuthn().getMfa().getDeviceRegistrationEnabled();
if (!registrationEnabled) { /* hide registration flow before invoking action */ } Prevention
- Keep the registration UI link gated on the same property the action checks.
- Audit per-service/per-tenant MFA overrides when disabling registration globally.
When it happens
Trigger: A user hits the OTP registration flow (OneTimeTokenAccountSaveRegistrationAction.execute) while the cas.authn.mfa.core... device-registration-enabled (mfa device registration feature) is disabled in configuration.
Common situations: Deployments that pre-provision devices out-of-band but leave the registration webflow reachable; environment-specific config where registration was disabled for production but users still navigate to the registration URL; stale SSO session landing users in the registration flow after an operator disabled registration.
Related errors
- Unable to register multiple devices for
- Not all requested multifactor providers could be found…
- List of candidate multifactor authentication providers is…
- Failed to authenticate code
- cannot be found in the registry
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/5e44174a529f5364.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-otp-mfa-core/src/main/java/org/apereo/cas/otp/web/flow/OneTimeTokenAccountSaveRegistrationAction.java:73
.validationCode(currentAcct.getValidationCode())
.scratchCodes(currentAcct.getScratchCodes())
.name(accountName)
.tenant(tenantExtractor.extract(requestContext).map(TenantDefinition::getId).orElse(StringUtils.EMPTY))
.build();
}
protected T getCandidateAccountFrom(final RequestContext requestContext) {
return (T) requestContext.getFlowScope()
.get(OneTimeTokenAccountCreateRegistrationAction.FLOW_SCOPE_ATTR_ACCOUNT, OneTimeTokenAccount.class);
}
@Override
protected @Nullable Event doExecuteInternal(final RequestContext requestContext) {
try {
val currentAcct = getCandidateAccountFrom(requestContext);
val deviceRegistrationEnabled = MultifactorAuthenticationWebflowUtils.isMultifactorDeviceRegistrationEnabled(requestContext);
if (!deviceRegistrationEnabled) {
LOGGER.warn("Device registration is disabled for [{}]", currentAcct.getUsername());
return getErrorEvent(requestContext);
}
if (!isMultipleDeviceRegistrationEnabled(requestContext)
&& repository.count(currentAcct.getUsername()) > 0) {
LOGGER.warn("Unable to register multiple devices for [{}]", currentAcct.getUsername());
return getErrorEvent(requestContext);
}
val account = (T) buildOneTimeTokenAccount(requestContext);
if (!validate(account, requestContext)) {
LOGGER.error("Unable to validate account [{}]", account);
return getErrorEvent(requestContext);
}
val validate = requestContext.getRequestParameters().getBoolean(REQUEST_PARAMETER_VALIDATE);
if (validate == null || !validate) {
LOGGER.trace("Storing account [{}]", account);
MultifactorAuthenticationWebflowUtils.putOneTimeTokenAccount(requestContext, repository.save(account));View on GitHub (pinned to e7288fc434)