passbolt/passbolt_api · error · Cake\Http\Exception\BadRequestException

Account recovery is disabled.

Error message

Account recovery is disabled.

What it means

`getOrFail` enforces that account recovery is enabled before serving the organization policy. When the stored organization policy row says disabled, a `BadRequestException('Account recovery is disabled.')` is raised because the requested operation only makes sense for an enabled setup.

Solutions

  1. Enable account recovery in Admin Workspace > Account Recovery Settings (policy set to opt-in/mandatory) with a valid organization key
  2. Verify via GET /account-recovery/organization-settings.json that the policy is not 'disabled'
  3. If the EE plugin was recently installed/removed, confirm the policy row exists and is enabled
Defensive patterns

Strategy: type-guard

Validate before calling

const s = await api.get('/account-recovery/organization-settings.json');
if (s.policy === 'disabled') throw new Error('enable account recovery first');

Type guard

function isRecoveryEnabled(settings) { return !!settings && settings.policy !== 'disabled'; }

Try / catch

try { await recoveryFlow(); } catch (e) { if (e.status === 400 && e.message.includes('disabled')) redirectAdminToEnableRecovery(); else throw e; }

Prevention

When it happens

Trigger: Calling APIs that require an active recovery policy (e.g. user account recovery setup/recovery flows) while the organization policy is 'disabled', or before EE account recovery has ever been enabled.

Common situations: CE instance without the EE account recovery plugin configured; admin never enabled recovery in admin settings; policy was disabled after users already attempted setup.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/23ff37c681d3a5ae. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryOrganizationPolicies/AccountRecoveryOrganizationPolicyGetService.php:89

            $policy = $this->AccountRecoveryOrganizationPolicies->newEntityForDefaultFallback();
        }

        return $policy;
    }

    /**
     * Throw an exception if the organization policy is disabled or
     * if the public key is empty
     *
     * @return \Passbolt\AccountRecovery\Model\Entity\AccountRecoveryOrganizationPolicy
     * @throws \Cake\Http\Exception\BadRequestException if the feature is not enabled
     * @throws \Cake\Http\Exception\BadRequestException if the public key is empty
     */
    public function getOrFail(): AccountRecoveryOrganizationPolicy
    {
        $policy = $this->get();
        if ($policy->isDisabled()) {
            throw new BadRequestException(__('Account recovery is disabled.'));
        } elseif (is_null($policy->account_recovery_organization_public_key)) {
            throw new BadRequestException(__('The account recovery organization public key is not set.'));
        }

        return $policy;
    }

    /**
     * Join the creator to the query if contained in the request
     * The Gpgkey of the creator may also be contained.
     *
     * @param \Cake\ORM\Query $query Query to decorate
     * @return void
     */
    protected function containCreator(Query $query): void
    {
        $contain = $this->request->getQuery('contain');
        if (is_array($contain) && isset($contain['creator']) && $contain['creator']) {

View on GitHub (pinned to 31c1bbc10f)