passbolt/passbolt_api · error · CustomValidationException

Could not validate private key data.

Error message

Could not validate private key data.

What it means

validateAccountRecoveryPrivateKey() collects errors from validating the armored private key entity and, if validation failed or no entity could be built, throws a generic CustomValidationException 'Could not validate private key data.' with the detailed errors nested under account_recovery_user_setting.account_recovery_private_key.

Solutions

  1. Read the nested errors in the response for the exact failing rule
  2. Ensure a valid openpgp armored PRIVATE key is submitted, complete with armor headers
  3. Verify the key matches the user's account key and the passwords decrypt it
  4. Validate the armored key client-side (openpgp.js) before sending

Example fix

// before
privateKey: user.publicArmoredKey
// after
privateKey: user.privateArmoredKey // decrypted/validated locally first
Defensive patterns

Strategy: validation

Validate before calling

const key = await openpgp.readKey({armoredKey}); if (key.isPublic() || key.isPrivate() === false) throw new Error('a private key is required');

Type guard

const isArmoredPrivateKey = (s) => typeof s === 'string' && s.includes('-----BEGIN PGP PRIVATE KEY BLOCK-----');

Try / catch

try { await setSettings(data); } catch (e) { const errs = e.body?.account_recovery_user_setting?.account_recovery_private_key; if (errs) showKeyErrors(errs); }

Prevention

When it happens

Trigger: Submitting an armored key that fails parsing/validation (bad armor, wrong key type, key not matching the user's key, wrong fingerprint); key encrypted with an unexpected passphrase; entity construction failing outright.

Common situations: Sending the public key instead of the private one; keys generated with unsupported algorithms; copy/paste truncation of the ASCII armor; passphrase mismatch with the provided key passwords.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryUserSettings/AccountRecoveryUserSettingsSetService.php:226

        try {
            // Entity validation &
            $privateKeyEntity = $this->AccountRecoveryPrivateKeys->buildAndValidateEntity($this->uac, $data);

            // Validate private key OpenPGP message &
            $rules = MessageValidationService::getSymmetricMessageRules();
            MessageValidationService::parseAndValidateMessage($privateKeyEntity->data, $rules);

            // Validate business rules
            if (!$this->AccountRecoveryPrivateKeys->checkRules($privateKeyEntity)) {
                $errors = $privateKeyEntity->getErrors();
            }
        } catch (CustomValidationException | ValidationException $exception) {
            $errors = $exception->getErrors();
        }

        if (isset($errors) || !isset($privateKeyEntity)) {
            $msg = __('Could not validate private key data.');
            throw new CustomValidationException($msg, [
                'account_recovery_user_setting' => [
                    'account_recovery_private_key' => $errors ?? [],
                ],
            ]);
        }

        return $privateKeyEntity;
    }

    /**
     * @return array<\Passbolt\AccountRecovery\Model\Entity\AccountRecoveryPrivateKeyPassword> array of AccountRecoveryPrivateKeyPasswords
     */
    public function buildPasswordEntitiesFromDataOrFail(): array
    {
        $passwordsData = $this->data['account_recovery_private_key']['account_recovery_private_key_passwords'] ?? [];
        try {
            $service = new AccountRecoveryPrivateKeyPasswordsValidationService();
            $publicKey = $this->organizationPolicy->account_recovery_organization_public_key->armored_key;

View on GitHub (pinned to 31c1bbc10f)