passbolt/passbolt_api · error · BadRequestException
Account recovery is mandatory. Please provide the mandatory…
Error message
Account recovery is mandatory. Please provide the mandatory data.
What it means
Thrown in AccountRecoverySetupCompleteService::assertRequestSanity when the organization account recovery policy is 'mandatory' but the setup complete request omits required data: the account recovery private key or the server-stored passwords. A mandatory policy requires the user to hand over the private key and account passwords for escrow.
Solutions
- Ensure the setup complete payload includes the account_recovery_private_key and all required password fields
- Update the browser extension / client to a version that supports mandatory account recovery
- If the policy should not be mandatory, change the organization account recovery setting to 'opt-in' or 'disabled' in admin settings
- Re-run the setup wizard from the start so the client collects the mandatory data
Example fix
// before
payload = { authenticationtoken: token, user_setting: '...' };
// after (mandatory policy)
payload = { ...payload, account_recovery_private_key: armoredKey, account_recovery_password: pwd }; Defensive patterns
Strategy: validation
Validate before calling
if (orgRecoveryPolicy === 'mandatory' &&
(!payload.account_recovery_private_key || !payload.account_recovery_password)) {
throw new Error('Mandatory recovery data missing');
} Type guard
const hasMandatoryRecoveryData = (p) => typeof p?.account_recovery_private_key === 'string' && p.account_recovery_private_key.length > 0 && typeof p?.account_recovery_password === 'string';
Try / catch
try {
await setupComplete(payload);
} catch (e) {
if (e.code === 400 && /mandatory/.test(e.message)) {
await collectMandatoryRecoveryData();
await setupComplete(buildPayloadWithRecoveryData());
} else { throw e; }
} Prevention
- Check the organization recovery policy early in the setup wizard and enforce required fields
- Use an up-to-date browser extension that supports mandatory recovery
- Do not bypass the 'provide key and passwords' step in scripted setups
- Alert admins that switching to 'mandatory' requires all clients to comply
When it happens
Trigger: POST /setup/setup/complete under a mandatory account recovery policy where the payload lacks account_recovery_private_key or the required password fields.
Common situations: Client (extension version mismatch or custom integration) not implementing the mandatory recovery fields; user bypassing the 'download mandatory data' step; policy changed to mandatory while an old client flow is mid-setup; API scripting/tests against a mandatory-policy instance without the fields.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Account recovery is disabled. Key backup is not supported.
- Could not save the account recovery setting.
- Invalid request. You cannot opt-out.
- The account recovery is mandatory and cannot be rejected.
- The account recovery request status is not approved.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/ef61546229d343a3.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/AccountRecovery/src/Service/Setup/AccountRecoverySetupCompleteService.php:134
}
/**
* Assert that there is not too much or not enough data
* Mandatory: both private key and password must be provided
* Disabled: none of them must be provided
*
* @return void
* @throws \Cake\Http\Exception\BadRequestException if data is missing or too much data is sent
*/
protected function assertRequestSanity(): void
{
if ($this->policy->isDisabled()) {
if ($this->isAccountRecoveryUserSettingProvided()) {
throw new BadRequestException(__('Account recovery is disabled. Key backup is not supported.'));
}
} elseif ($this->policy->isMandatory()) {
if (!$this->isPrivateKeyProvided() || !$this->arePasswordsProvided()) {
throw new BadRequestException(
__('Account recovery is mandatory. Please provide the mandatory data.')
);
}
}
}
/**
* @return bool true if the account_recovery_user_setting data is set
*/
protected function isAccountRecoveryUserSettingProvided(): bool
{
return is_array($this->request->getData('account_recovery_user_setting'));
}
/**
* @return bool true if the account_recovery_user_setting.account_recovery_private_key data is set
*/
protected function isPrivateKeyProvided(): boolView on GitHub (pinned to 31c1bbc10f)