passbolt/passbolt_api · error · Cake\Http\Exception\BadRequestException
Invalid request. Revoked key is required for key rotation.
Error message
Invalid request. Revoked key is required for key rotation.
What it means
When the policy value stays the same but a NEW public key is supplied, Passbolt interprets this as a key rotation, which requires also providing the revoked (old) key. Without the revoked key the old key could not be properly marked revoked, so the request is rejected.
Solutions
- Include the old active key as the revoked key in the same request (armored_key for revocation + new key)
- Follow the documented rotation payload: policy (unchanged), new public key, and revoked key together
- If you don't want rotation, remove the new key from the payload
Example fix
// before
await api.put('/account-recovery/organization-settings.json', { policy: 'opt-in', new_key: newPublicKey });
// after
const active = await getActiveOrgKey();
await api.put('/account-recovery/organization-settings.json', { policy: 'opt-in', new_key: newPublicKey, revoked_key: active.armored_key }); Defensive patterns
Strategy: validation
Validate before calling
if (newKey && !revokedKey && currentPolicy === desiredPolicy) throw new Error('rotation requires the old key too'); Try / catch
try { await updateSettings(payload); } catch (e) { if (e.message.includes('Revoked key is required')) attachActiveKeyAndRetry(); else throw e; } Prevention
- Build rotation payloads atomically (new key + revoked key)
- Follow documented rotation payload shape
- Unit-test client payload builders per scenario
When it happens
Trigger: PUT with unchanged policy plus `armored_key` (new key) but without the `revoked_key`/old key payload — e.g. partial payload from a client that forgot the old key.
Common situations: UI sends only the new key field during rotation; admin tries to 'replace' the key without revoking the old one; incomplete migration scripts.
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
- Invalid request. New key is required for key rotation.
- An authentication token should be provided.
- Invalid request. Keys are required for this change.
- Invalid request. Passwords are required for this change.
- Account recovery case must be a string.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/8f35c8fc0d1c34e2.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryOrganizationPolicies/AccountRecoveryOrganizationPolicySetService.php:56
public function set(UserAccessControl $uac, array $data): AccountRecoveryOrganizationPolicy
{
$this->setData($data);
// 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);View on GitHub (pinned to 31c1bbc10f)