passbolt/passbolt_api · error · Cake\Http\Exception\BadRequestException
Recovery request cannot be created when organization policy…
Error message
Recovery request cannot be created when organization policy is disabled.
What it means
AccountRecoveryRequestCreateService::assertPolicyIsEnabled fetches the organization account-recovery policy via AccountRecoveryOrganizationPolicyGetService and throws BadRequestException if the policy is disabled. Account recovery requests are only allowed while the organization policy is enabled ('mandatory' or 'opt-in'), so requests against a disabled policy are rejected up front.
Solutions
- Have an administrator re-enable account recovery in the organization settings (set policy to 'opt-in' or 'mandatory') before retrying
- Check the current policy via GET /account-recovery/organization-policies to confirm it is disabled
- Use an alternative account-recovery route (e.g. admin-assisted recovery or the recovery token from email) while the policy is disabled
- Ensure the AccountRecovery plugin settings were fully saved/enabled if you expected it to be on
Example fix
// before (org policy disabled)
PUT /account-recovery/organization-policies {"policy": "disabled"} → POST /account-recovery/requests fails
// after (enable first, then request)
PUT /account-recovery/organization-policies {"policy": "opt-in"}
POST /account-recovery/requests {"user_id": "...", "authentication_token": {...}} Defensive patterns
Strategy: try-catch
Validate before calling
// Check policy state before attempting a recovery request:
$policy = (new AccountRecoveryOrganizationPolicyGetService())->get();
if ($policy->isDisabled()) {
// do not call create(); surface 'account recovery disabled' to the user instead
} Type guard
$policyIsUsable = fn($policy): bool => !$policy->isDisabled()
&& in_array($policy->policy, ['opt-in', 'mandatory'], true); Try / catch
try {
$request = $createService->create($uac, $data);
} catch (\Cake\Http\Exception\BadRequestException $e) {
if (str_contains($e->getMessage(), 'organization policy is disabled')) {
// guide user/admin to enable the policy or use an alternative recovery path
}
} Prevention
- Fetch GET /account-recovery/organization-policies before offering the recovery UI to users
- Hide/disable the self-recovery flow in clients when the policy is disabled
- Coordinate with admins: disabling the policy mid-flight breaks in-progress recoveries
- On instances where recovery is expected, verify plugin settings were saved during setup
When it happens
Trigger: POST /account-recovery/requests while the organization setting account_recovery_organization_policy is 'disabled' — e.g. an admin disabled recovery after the user's client cached an enabled state, or the feature was never enabled on the instance.
Common situations: Admin turned the policy off while users were mid-recovery; fresh instance where account recovery was never enabled; plugin installed but organization settings still disabled; users with stale bookmarks/automation hitting the endpoint post-disable.
Related errors
- The user does not exist or has been deleted.
- Account recovery case must be a string.
- Account recovery is disabled.
- Account recovery is disabled. Key backup is not supported.
- Account recovery is mandatory. Please provide the mandatory…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/19bd446efec5feaf.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryRequests/AccountRecoveryRequestCreateService.php:121
}
$event = new Event(static::REQUEST_CREATED_EVENT_NAME, $request);
EventManager::instance()->dispatch($event);
return $request;
}
/**
* @throws \Cake\Http\Exception\BadRequestException if organization policy is disabled
* @return void
*/
public function assertPolicyIsEnabled(): void
{
$service = new AccountRecoveryOrganizationPolicyGetService();
$policy = $service->get();
if ($policy->isDisabled()) {
$msg = __('Recovery request cannot be created when organization policy is disabled.');
throw new BadRequestException($msg);
}
}
/**
* @throws \Cake\Http\Exception\BadRequestException if user id is not valid
* @return string uuid
*/
public function assertUserId(): string
{
$userId = $this->getData('user_id');
if (!Validation::uuid($userId)) {
throw new BadRequestException(__('The user identifier should be a valid UUID.'));
}
return $userId;
}
/**View on GitHub (pinned to 31c1bbc10f)