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

Invalid request. New key is required for key rotation.

Error message

Invalid request. New key is required for key rotation.

What it means

Composition guard in the account recovery organization policy set service: the request neither changes the policy nor provides the new server key required for key rotation, so the requested operation is undetermined/invalid for key rotation and is rejected.

Solutions

  1. Provide both the new public key and the revoked old key in the same request
  2. If the goal is to disable recovery entirely, set the policy to 'disabled' instead of sending a revoked key
  3. If no change is intended, omit both keys

Example fix

// before
await api.put('/account-recovery/organization-settings.json', { policy: 'opt-in', revoked_key: oldKey });
// after
await api.put('/account-recovery/organization-settings.json', { policy: 'opt-in', new_key: newPublicKey, revoked_key: oldKey });
Defensive patterns

Strategy: validation

Validate before calling

if (revokedKey && !newKey && currentPolicy === desiredPolicy) throw new Error('rotation requires a new key');

Try / catch

try { await updateSettings(payload); } catch (e) { if (e.message.includes('New key is required')) promptForNewKey(); else throw e; }

Prevention

When it happens

Trigger: PUT with unchanged policy and only the revoked key payload — client intends to revoke but forgot to attach the new organization public key.

Common situations: Confusion between 'revoke' and 'rotate' semantics; UI bug dropping the new-key field; admin thinks revoking alone is valid while the policy stays enabled.

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


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

Appendix: source

Thrown at plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryOrganizationPolicies/AccountRecoveryOrganizationPolicySetService.php:60

        // assert policy is provided as it should in any case
        $newPolicy = $this->buildAndValidatePolicyEntityFromData($uac);

        // Check request composition to understand user goal
        $isPolicyChange = $this->isPolicyChange();
        $isNewKeyProvided = $this->isPublicKeyProvided();
        $isRevokedKeyProvided = $this->isRevokedKeyProvided();
        $isPrivateKeyPasswordsProvided = $this->isPrivateKeyPasswordsProvided();

        // if policy has not changed and (new key not provided or revoked key not provided)
        if (!$isPolicyChange && !$isNewKeyProvided && !$isRevokedKeyProvided) {
            throw new BadRequestException(__('Invalid request. No policy change.'));
        }
        if (!$isPolicyChange && $isNewKeyProvided && !$isRevokedKeyProvided) {
            throw new BadRequestException(__('Invalid request. Revoked key is required for key rotation.'));
        }
        /** @psalm-suppress RedundantCondition */
        if (!$isPolicyChange && !$isNewKeyProvided && $isRevokedKeyProvided) {
            throw new BadRequestException(__('Invalid request. New key is required for key rotation.'));
        }

        // if disabled => enabled
        if ($this->isEnabling()) {
            // if public key is not provided
            if (!$isNewKeyProvided) {
                throw new BadRequestException(__('Invalid request. An organization recovery public key is required.'));
            }
            // if key revocation or passwords provided
            if ($isRevokedKeyProvided || $isPrivateKeyPasswordsProvided) {
                throw new BadRequestException(__('Invalid request. Revoked key or passwords are not required.'));
            }

            return $this->enablePolicy($uac, $newPolicy);
        }

        // if enabled => disabled
        if ($this->isDisabling()) {

View on GitHub (pinned to 31c1bbc10f)