passbolt/passbolt_api · warning · BadRequestException

The multi-factor authentication is not required.

Error message

The multi-factor authentication is not required.

What it means

During MFA verification the controller checks whether MFA is actually required for the current request; if an existing MFA verified token is still valid, verification is unnecessary and a BadRequestException is thrown instead of issuing a redundant verification.

Solutions

  1. Skip the verify call — the session is already MFA verified
  2. Clear the stale MFA verified cookie/token if a fresh verification is truly needed
  3. Fix client logic to track verification state and avoid redundant verify requests

Example fix

// before: always calling verify
await http.post('/mfa/verify/totp.json', {totp});
// after: check state first
if (!mfaIsVerified) await http.post('/mfa/verify/totp.json', {totp});
Defensive patterns

Strategy: validation

Validate before calling

const verified = await isMfaVerified();
if (verified) return; // skip verify call

Try / catch

try { await mfaVerify(provider, token); } catch (e) { if (/not required/.test(e.message)) return; throw e; }

Prevention

When it happens

Trigger: GET/POST to /mfa/verify when the user's MFA verified cookie/token is already valid for this session (isValid === true in _handleVerifiedNotRequired) and MFA is not pending.

Common situations: Client repeating verify after a successful verification; double-submitting the verify form; cached token still present while the frontend forces the verify screen.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/df35075fb6366ee4. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Controller/MfaVerifyController.php:81

     * @return void
     */
    protected function _handleVerifiedNotRequired(
        SessionIdentificationServiceInterface $sessionIdentificationService,
        ?RememberAMonthSettingInterface $rememberMeForAMonthSetting = null
    ) {
        // Mfa cookie is set and a valid token
        $uac = $this->User->getAccessControl();
        $mfaVerifiedToken = $this->request->getCookie(MfaVerifiedCookie::MFA_COOKIE_ALIAS);
        if (isset($mfaVerifiedToken)) {
            $isValid = MfaVerifiedToken::check(
                $uac,
                $mfaVerifiedToken,
                $sessionIdentificationService,
                $this->getRequest(),
                $rememberMeForAMonthSetting
            );
            if ($isValid) {
                throw new BadRequestException(__('The multi-factor authentication is not required.'));
            }
        }
    }

    /**
     * Trigger an error if current MFA settings do not allow verify for the given provider.
     *
     * Callers MUST return the response when a non-null value is returned; otherwise the request
     * will continue to execute past a disabled provider and can mint an MFA cookie.
     *
     * @param string $provider name of the provider
     * @return \Cake\Http\Response|null redirect response for non-JSON requests, null when settings are valid
     * @throws \Cake\Http\Exception\BadRequestException on JSON requests with invalid settings
     */
    protected function _handleInvalidSettings(string $provider): ?Response
    {
        if ($this->mfaSettings->getAccountSettings() === null) {
            if ($this->getRequest()->is('json')) {

View on GitHub (pinned to 31c1bbc10f)