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

  1. Have an administrator re-enable account recovery in the organization settings (set policy to 'opt-in' or 'mandatory') before retrying
  2. Check the current policy via GET /account-recovery/organization-policies to confirm it is disabled
  3. Use an alternative account-recovery route (e.g. admin-assisted recovery or the recovery token from email) while the policy is disabled
  4. 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

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


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)