apereo/cas · warning

No registered devices for multifactor authentication could…

Error message

No registered devices for multifactor authentication could be found for [{}] via [{}]

What it means

InitPasswordResetAction checks, when password reset requires MFA, whether the resolved principal has registered devices with the selected MFA provider's device manager. If none exist, it warns 'No registered devices for multifactor authentication could be found for [{}] via [{}]' and returns the error event, halting password reset.

Solutions

  1. Have the user enroll a device with the MFA provider before attempting password reset
  2. Configure password management so reset MFA falls back to an alternative provider (or a fallback channel) when no devices exist
  3. Review cas.pm.reset.mfa / multifactor provider selection policy for the account
  4. Verify the device manager is backed by the correct registration storage (data source) so existing devices are found

Example fix

// before
cas.pm.reset.mfa.webflow-enabled=true  # no fallback, user has no devices
// after  # enable fallback via a secondary provider or allow security questions
cas.pm.reset.security-questions-enabled=true
Defensive patterns

Strategy: fallback

Validate before calling

if (provider.getDeviceManager() != null && !provider.getDeviceManager().hasRegisteredDevices(principal)) {
    // fall back to alternate reset channel before entering the flow
}

Try / catch

try { selectMultifactorAuthenticationProvider(...); } catch (Exception e) { LOGGER.warn("MFA provider selection failed", e); return alternateResetChannel(); }

Prevention

When it happens

Trigger: User starts password reset; password-management policy requires MFA; the resolved MFA provider (e.g. WebAuthn) is selected but its DeviceManager reports no registered devices for that principal.

Common situations: Users who never enrolled a device (e.g. no WebAuthn credential) trying to reset passwords, or MFA provider misconfiguration selecting a provider the user has no devices for; also occurs after device deregistration.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-pm-webflow/src/main/java/org/apereo/cas/pm/web/flow/actions/InitPasswordResetAction.java:61

    private final MultifactorAuthenticationProviderSelector multifactorAuthenticationProviderSelector;
    private final AuthenticationSystemSupport authenticationSystemSupport;
    private final MultifactorAuthenticationContextValidator multifactorAuthenticationContextValidator;

    @Override
    protected @Nullable Event doExecuteInternal(final RequestContext requestContext) throws Throwable {
        val username = getPasswordResetUsername(requestContext);
        if (StringUtils.isBlank(username)) {
            LOGGER.error("Password reset token could not be verified to determine username");
            return error();
        }

        if (doesPasswordResetRequireMultifactorAuthentication(requestContext)) {
            val resolvedPrincipal = resolvedPrincipal(username);
            val provider = selectMultifactorAuthenticationProvider(requestContext, resolvedPrincipal);
            if (!doesMultifactorAuthenticationProviderExistInContext(requestContext, provider)) {
                val deviceManager = provider.getDeviceManager();
                if (deviceManager != null && !deviceManager.hasRegisteredDevices(resolvedPrincipal)) {
                    LOGGER.warn("No registered devices for multifactor authentication could be found for [{}] via [{}]", resolvedPrincipal.getId(), provider.getId());
                    return error();
                }
                return routeToMultifactorAuthenticationProvider(requestContext, resolvedPrincipal, provider);
            }
        }
        val credential = new UsernamePasswordCredential();
        credential.setUsername(username);
        WebUtils.putCredential(requestContext, credential);
        return success();
    }

    protected Event routeToMultifactorAuthenticationProvider(final RequestContext requestContext,
                                                             final Principal resolvedPrincipal,
                                                             final MultifactorAuthenticationProvider provider) {
        val authentication = DefaultAuthenticationBuilder.newInstance().setPrincipal(resolvedPrincipal).build();
        WebUtils.putAuthentication(authentication, requestContext);
        val builder = authenticationSystemSupport.getAuthenticationResultBuilderFactory().newBuilder();
        val authenticationResult = builder.collect(authentication);

View on GitHub (pinned to e7288fc434)