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

  1. Inspect errors.account_recovery_organization_public_key in the exception/response for the nested rule failure
  2. Verify armored_key is complete valid ASCII armor including BEGIN/END PGP PUBLIC KEY BLOCK lines
  3. Ensure the submitted fingerprint equals the SHA-1 fingerprint of the armored key
  4. 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

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


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_key

View on GitHub (pinned to 31c1bbc10f)