{"record":{"id":"f14b22558260f82b","repo":"n8n-io/n8n","slug":"mfa-secret-could-not-be-verified","errorCode":null,"errorMessage":"MFA secret could not be verified","messagePattern":"MFA secret could not be verified","errorType":"exception","errorClass":"BadRequestError","httpStatus":400,"severity":"error","filePath":"packages/cli/src/controllers/mfa.controller.ts","lineNumber":216,"sourceCode":"\t}\n\n\t@Post('/verify', {\n\t\tallowSkipMFA: true,\n\t\tkeyedRateLimit: createUserKeyedRateLimiter({}),\n\t})\n\tasync verifyMFA(req: MFA.Verify) {\n\t\tconst { id } = req.user;\n\t\tconst { mfaCode } = req.body;\n\n\t\tconst { decryptedSecret: secret } = await this.mfaService.getSecretAndRecoveryCodes(id);\n\n\t\tif (!mfaCode) throw new BadRequestError('MFA code is required to enable MFA feature');\n\n\t\tif (!secret) throw new BadRequestError('No MFA secret se for this user');\n\n\t\tconst verified = this.mfaService.totp.verifySecret({ secret, mfaCode });\n\n\t\tif (!verified) throw new BadRequestError('MFA secret could not be verified');\n\t}\n}\n","sourceCodeStart":198,"sourceCodeEnd":219,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/cli/src/controllers/mfa.controller.ts#L198-L219","documentation":"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.","triggerScenarios":"POST /rest/mfa/verify with a non-empty mfaCode that does not match the current TOTP value for the user's secret.","commonSituations":"Typo in the 6 digits, code expired between typing and submit, device clock drift, wrong authenticator entry.","solutions":["Enter a freshly generated code immediately before submitting.","Sync the device clock (TOTP is time-sensitive).","If persistent, re-enroll: disable/QR/enable flow to reseed the authenticator."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Shape-only; validity is determined server-side.\nif (!/^\\d{6}$/.test(mfaCode)) throw new Error('Enter a 6-digit code.');","typeGuard":null,"tryCatchPattern":"try {\n  await restApi.post('/mfa/verify', { mfaCode });\n} catch (e) {\n  if (/could not be verified/i.test(e.response?.data?.message)) {\n    promptFreshCode('Code rejected — enter a fresh one.');\n  } else throw e;\n}","preventionTips":["Submit immediately after the user enters the code (TOTP is time-boxed).","Sync the device clock if verification keeps failing across endpoints.","Offer a re-enroll path if the user's authenticator is permanently out of sync."],"tags":["mfa","totp","verification"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}