medusajs/medusa · error · MedusaError
Only TOTP MFA factors can be verified with this method
Error message
Only TOTP MFA factors can be verified with this method
What it means
verifySetup on the TOTP provider only verifies factors whose provider is 'totp'. Passing the id of a factor created by a different MFA provider (e.g. another OTP method) throws INVALID_DATA.
Source
Thrown at packages/modules/auth/src/providers/mfa/totp.ts:132
secret,
digits: totpConfig.digits,
period: totpConfig.period,
}),
}
}
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")
}
View on GitHub (pinned to 5e06e544a2)
Solutions
- Fetch the factor and route verification to the provider stored on it (factor.provider)
- Check that the factor id passed corresponds to a TOTP setup
Example fix
// before
await totpProvider.verifySetup({ id: factorId, code })
// after
const [factor] = await authModuleService.listAuthMfaFactors(identityId)
const provider = factor.provider // route to matching provider
await mfaProviderService.verifySetup(factor.provider, { id: factor.id, code }) Defensive patterns
Strategy: type-guard
Validate before calling
const [factor] = await authModuleService.listAuthMfaFactors(identityId)
if (factor.provider !== 'totp') throw new Error('route to the correct provider') Type guard
const isTotpFactor = (f: { provider: string }) => f.provider === 'totp' Prevention
- Always dispatch verification to the provider stored on the factor row
- Don't hardcode provider names in generic confirm routes
When it happens
Trigger: confirmAuthMfaFactor / verifySetup({ id }) where the factor row's provider column is not 'totp' — e.g. ids mixed up between provider setups or a generic confirm route hardcoded to the totp provider.
Common situations: Frontend sends a factor id from the wrong provider after multiple MFA methods are enabled; copy-pasted factor ids between environments.
Related errors
- An active TOTP factor already exists for this auth identity
- Disabled MFA factors cannot be verified
- Invalid TOTP code
- MFA verification code is required to disable MFA
- Invalid MFA verification code
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/2224eebbe056b879.
Report an issue: GitHub.