passbolt/passbolt_api · error · CustomValidationException
Something went wrong when validating the one-time password.
Error message
Something went wrong when validating the one-time password.
What it means
The base MFA form's `execute()` throws a CustomValidationException when the submitted data fails the form's validation rules (e.g. a bad TOTP code or missing field). The message is generic on purpose; the precise per-field reasons are returned in the attached `getErrors()` array.
Solutions
- Read the `body.errors` object in the API response for the exact failing field(s)
- Regenerate/resynchronize the authenticator app time and retry with a fresh code
- Ensure all required fields (e.g. `totp`) are present in the JSON payload
- If verifying Yubikey, confirm the org Yubikey client-id/secret-key settings exist
Example fix
// before
const res = await post('/mfa/verify/totp.json', {totp: code});
if (!res.ok) alert('invalid code');
// after
const res = await post('/mfa/verify/totp.json', {totp: code});
if (!res.ok) {
const errs = (await res.json()).errors; // per-field details
showFieldErrors(errs);
} Defensive patterns
Strategy: try-catch
Validate before calling
const TOTP_RE = /^\d{6}$/;
if (!TOTP_RE.test(otp)) throw new Error('OTP must be exactly 6 digits'); Type guard
function isValidTotp(v) { return typeof v === 'string' && /^\d{6}$/.test(v); } Try / catch
try { await verifyMfa(data); } catch (e) {
if (e.response?.data?.errors) showFieldErrors(e.response.data.errors);
} Prevention
- Always inspect the errors object in the response for per-field reasons
- Validate OTP format client-side before submitting
- Keep authenticator clocks synchronized
- Send the payload as JSON with all required fields
When it happens
Trigger: POSTing MFA verify/setup data that fails the form's rules: empty or non-6-digit OTP, wrong TOTP code, missing `otp` field, invalid Yubikey HOTP format, or data not matching the declared validation schema.
Common situations: Authenticator app out of sync (TOTP window passed); users submitting the recovery code into the OTP field; frontend sending form data as multipart instead of JSON so fields are missing; expired provisioning URI.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- A Duo state cookie is required.
- A Duo state cookie is required.
- Could not generate enough random bytes, please try again…
- Could not generate TOTP secret, please try again later.
- Could not save the SSO state, invalid nonce.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/2ea4aef93e87e408.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/MultiFactorAuthentication/src/Form/MfaForm.php:57
}
/**
* Execute the form if it is valid.
*
* First validates the form, then calls the `process()` hook method.
* This hook method can be implemented in subclasses to perform
* the action of the form. This may be sending email, interacting
* with a remote API, or anything else you may need.
*
* @param array $data Form data.
* @param array<string, mixed> $options List of options.
* @return bool False on validation failure, otherwise returns the
* result of the `process()` method.
*/
public function execute(array $data, array $options = []): bool
{
if (!$this->validate($data)) {
throw new CustomValidationException(
__('Something went wrong when validating the one-time password.'),
$this->getErrors()
);
}
return $this->process($data);
}
}
View on GitHub (pinned to 31c1bbc10f)