passbolt/passbolt_api · error · CustomValidationException
Could not validate policy data.
Error message
Could not validate policy data.
What it means
Wrapper error thrown by buildPublicKeyEntityFromDataOrFail when any ValidationException or CustomValidationException occurs while validating the organization recovery public key (armored key parsing, fingerprint match, key model rules, or canEncrypt check). The original errors are nested under 'account_recovery_organization_public_key'.
Solutions
- Inspect errors.account_recovery_organization_public_key in the exception/response for the nested rule failure
- Verify armored_key is complete valid ASCII armor including BEGIN/END PGP PUBLIC KEY BLOCK lines
- Ensure the submitted fingerprint equals the SHA-1 fingerprint of the armored key
- If reusing a key, check it is not already active (prevent key reuse rule); generate a new key if needed
Example fix
// before
{"fingerprint": "ABC...", "armored_key": "<truncated armor>"}
// after
{"fingerprint": "<full 40-char fingerprint of the key>", "armored_key": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n...\n-----END PGP PUBLIC KEY BLOCK-----"} Defensive patterns
Strategy: validation
Validate before calling
function validateOrgKeyPayload({armored_key, fingerprint}) {
if (!armored_key?.includes('-----BEGIN PGP PUBLIC KEY BLOCK-----')) return 'armor';
if (!/^[0-9A-F]{40}$/.test(fingerprint)) return 'fingerprint';
return null;
} Type guard
function isWellFormedOrgKeyPayload(p) {
return typeof p.armored_key === 'string'
&& p.armored_key.includes('BEGIN PGP PUBLIC KEY BLOCK')
&& /^[0-9A-F]{40}$/.test(p.fingerprint);
} Try / catch
try {
await api.setOrganizationPolicy(payload);
} catch (e) {
const nested = e.body?.errors?.account_recovery_organization_public_key;
// nested mirrors the inner ValidationException errors; log and fix per field
console.error(nested);
} Prevention
- Copy the full armored block including BEGIN/END lines
- Compute and send the fingerprint from the same key material (gpg --fingerprint)
- Avoid uploading a fingerprint/key pair already active in the organization
When it happens
Trigger: Calling set() or enablePolicy() with policy data whose public key fails any validation: malformed armor, fingerprint mismatch with armored_key, key reuse (same fingerprint already active), or a non-encryption-capable key.
Common situations: Copy/paste truncating the armored key block; submitting a fingerprint that doesn't match the key; re-uploading the same organization key for a second policy change; whitespace/newline corruption of the ASCII armor.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Could not save the account recovery private key.
- Could not validate key revocation.
- Could not validate public key data.
- The OpenPGP key can not be used to encrypt.
- A valid OpenPGP key must be provided.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/c88e53fe38c09aba.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryOrganizationPolicies/AbstractAccountRecoveryOrganizationPolicySetService.php:274
$data = $this->getData('account_recovery_organization_public_key');
$entity = $this->AccountRecoveryOrganizationPublicKeys->buildAndValidateEntity($uac, $data);
// Check key can be parsed
PublicKeyValidationService::parseAndValidatePublicKey(
$entity->armored_key,
PublicKeyValidationService::getStrictRules()
);
// Prevent key reuse
$this->assertPublicKeyModelRules($entity);
// Make sure key can be used to encrypt - ref. PBL-07-002
if (!PublicKeyCanEncryptCheckService::check($entity->armored_key, $entity->fingerprint)) {
$msg = __('The OpenPGP key can not be used to encrypt.');
throw new CustomValidationException($msg, ['armored_key' => ['canEncrypt' => $msg]]);
}
} catch (ValidationException | CustomValidationException $exception) {
throw new CustomValidationException(__('Could not validate policy data.'), [
'account_recovery_organization_public_key' => $exception->getErrors(),
]);
} catch (Exception $exception) {
throw new CustomValidationException(__('Could not validate policy data.'), [
'account_recovery_organization_public_key' => [
'armored_key' => [
'invalidArmoredKey' => $exception->getMessage(),
],
],
]);
}
return $entity;
}
/**
* Assert public key revocation
* Check user provided valid valid account_recovery_organization_revoked_keyView on GitHub (pinned to 31c1bbc10f)