n8n-io/n8n · error · BadRequestError

MFA secret could not be verified

Error message

MFA secret could not be verified

What it means

POST /rest/mfa/verify: the supplied code failed TOTP verification against the stored secret (`totp.verifySecret` returned false, no window slack). Indicates a wrong or expired code rather than a missing secret or missing code.

Source

Thrown at packages/cli/src/controllers/mfa.controller.ts:216

	}

	@Post('/verify', {
		allowSkipMFA: true,
		keyedRateLimit: createUserKeyedRateLimiter({}),
	})
	async verifyMFA(req: MFA.Verify) {
		const { id } = req.user;
		const { mfaCode } = req.body;

		const { decryptedSecret: secret } = await this.mfaService.getSecretAndRecoveryCodes(id);

		if (!mfaCode) throw new BadRequestError('MFA code is required to enable MFA feature');

		if (!secret) throw new BadRequestError('No MFA secret se for this user');

		const verified = this.mfaService.totp.verifySecret({ secret, mfaCode });

		if (!verified) throw new BadRequestError('MFA secret could not be verified');
	}
}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Enter a freshly generated code immediately before submitting.
  2. Sync the device clock (TOTP is time-sensitive).
  3. If persistent, re-enroll: disable/QR/enable flow to reseed the authenticator.
Defensive patterns

Strategy: try-catch

Validate before calling

// Shape-only; validity is determined server-side.
if (!/^\d{6}$/.test(mfaCode)) throw new Error('Enter a 6-digit code.');

Try / catch

try {
  await restApi.post('/mfa/verify', { mfaCode });
} catch (e) {
  if (/could not be verified/i.test(e.response?.data?.message)) {
    promptFreshCode('Code rejected — enter a fresh one.');
  } else throw e;
}

Prevention

When it happens

Trigger: POST /rest/mfa/verify with a non-empty mfaCode that does not match the current TOTP value for the user's secret.

Common situations: Typo in the 6 digits, code expired between typing and submit, device clock drift, wrong authenticator entry.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/f14b22558260f82b. Report an issue: GitHub.