medusajs/medusa · error · MedusaError

Disabled MFA factors cannot be verified

Error message

Disabled MFA factors cannot be verified

What it means

The TOTP factor exists and is a TOTP factor, but its status is 'disabled'. Disabled factors cannot be verified; they must be re-enabled (or a new factor created) before use.

Source

Thrown at packages/modules/auth/src/providers/mfa/totp.ts:139

  async verifySetup(
    data: AuthTypes.AuthMfaVerifyDTO,
    sharedContext: Context = {}
  ): Promise<AuthTypes.AuthMfaDTO> {
    const factor = await this.authMfaFactorService_.retrieve(
      data.id,
      {},
      sharedContext
    )

    if (factor.provider !== this.method) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "Only TOTP MFA factors can be verified with this method"
      )
    }

    if (factor.status === "disabled") {
      throw new MedusaError(
        MedusaError.Types.NOT_ALLOWED,
        "Disabled MFA factors cannot be verified"
      )
    }

    const valid = this.verifyCode_(factor, data.code)

    if (!valid) {
      throw new MedusaError(MedusaError.Types.NOT_ALLOWED, "Invalid TOTP code")
    }

    const verifiedFactor =
      factor.status === "pending"
        ? await this.authMfaFactorService_.update(
            { id: factor.id, status: "enabled" },
            sharedContext
          )
        : factor

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Filter factor lists by status === 'enabled' or 'pending' before offering verification
  2. Start a new TOTP setup for the identity instead of verifying the disabled factor
Defensive patterns

Strategy: validation

Validate before calling

if (factor.status === 'disabled') { /* restart setup instead of verifying */ }

Type guard

const isVerifiable = (f: { status: string }) => f.status === 'enabled' || f.status === 'pending'

Prevention

When it happens

Trigger: confirmAuthMfaFactor with the id of a factor whose status was set to 'disabled' (previously disabled by the user or an admin) while still passing a code to verify.

Common situations: User disabled authenticator MFA, stale frontend state still shows the old setup and submits its code; scripts verifying factors listed without filtering by status.

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 medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/91546f4e83b64bee. Report an issue: GitHub.