apereo/cas · warning

Unable to register multiple devices for

Error message

Unable to register multiple devices for [{}]

What it means

This warning is logged by OneTimeTokenAccountSaveRegistrationAction.doExecuteInternal when multiple-device registration is disabled (isMultipleDeviceRegistrationEnabled returns false) and the user already has at least one registered OTP device (repository.count(username) > 0). The action returns the error event rather than registering a second device.

Solutions

  1. Enable multiple device registration (cas.authn.mfa.trusted-device... / otp multiple-device-registration-enabled=true in the OTP MFA properties) if users should enroll more than one device.
  2. Direct the user to manage/delete their existing device before enrolling a new one, instead of registering again.
  3. Clear the user's existing registered device(s) from the OTP account repository if re-enrollment should be allowed under single-device policy.

Example fix

// before: cas.properties
cas.authn.mfa.otp.multiple-device-registration-enabled=false
// after
cas.authn.mfa.otp.multiple-device-registration-enabled=true
Defensive patterns

Strategy: validation

Validate before calling

boolean multiAllowed = casProperties.getAuthn().getMfa().getOtp().isMultipleDeviceRegistrationEnabled();
boolean hasDevices = otpAccountRepository.count(username) > 0;
if (hasDevices && !multiAllowed) { /* redirect user to device management instead */ }

Prevention

When it happens

Trigger: User with an existing registered OTP device submits the device registration action again while multiple device registration is disabled in the OTP MFA configuration.

Common situations: Users re-visiting the registration screen after already enrolling a device; test accounts reused across enrollment attempts; deployments that expect multi-device support but never enabled the multi-device setting.

Related errors


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

    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));
            }
            return success();
        } catch (final Exception e) {
            LoggingUtils.error(LOGGER, e);
        }
        return getErrorEvent(requestContext);

View on GitHub (pinned to e7288fc434)