{"record":{"id":"c88e53fe38c09aba","repo":"passbolt/passbolt_api","slug":"could-not-validate-policy-data-c88e53","errorCode":null,"errorMessage":"Could not validate policy data.","messagePattern":"Could not validate policy data\\.","errorType":"validation","errorClass":"CustomValidationException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryOrganizationPolicies/AbstractAccountRecoveryOrganizationPolicySetService.php","lineNumber":274,"sourceCode":"            $data = $this->getData('account_recovery_organization_public_key');\n            $entity = $this->AccountRecoveryOrganizationPublicKeys->buildAndValidateEntity($uac, $data);\n\n            // Check key can be parsed\n            PublicKeyValidationService::parseAndValidatePublicKey(\n                $entity->armored_key,\n                PublicKeyValidationService::getStrictRules()\n            );\n\n            // Prevent key reuse\n            $this->assertPublicKeyModelRules($entity);\n\n            // Make sure key can be used to encrypt - ref. PBL-07-002\n            if (!PublicKeyCanEncryptCheckService::check($entity->armored_key, $entity->fingerprint)) {\n                $msg = __('The OpenPGP key can not be used to encrypt.');\n                throw new CustomValidationException($msg, ['armored_key' => ['canEncrypt' => $msg]]);\n            }\n        } catch (ValidationException | CustomValidationException $exception) {\n            throw new CustomValidationException(__('Could not validate policy data.'), [\n                'account_recovery_organization_public_key' => $exception->getErrors(),\n            ]);\n        } catch (Exception $exception) {\n            throw new CustomValidationException(__('Could not validate policy data.'), [\n                'account_recovery_organization_public_key' => [\n                    'armored_key' => [\n                        'invalidArmoredKey' => $exception->getMessage(),\n                    ],\n                ],\n            ]);\n        }\n\n        return $entity;\n    }\n\n    /**\n     * Assert public key revocation\n     * Check user provided valid valid account_recovery_organization_revoked_key","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryOrganizationPolicies/AbstractAccountRecoveryOrganizationPolicySetService.php#L256-L292","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n{\"fingerprint\": \"ABC...\", \"armored_key\": \"<truncated armor>\"}\n// after\n{\"fingerprint\": \"<full 40-char fingerprint of the key>\", \"armored_key\": \"-----BEGIN PGP PUBLIC KEY BLOCK-----\\n...\\n-----END PGP PUBLIC KEY BLOCK-----\"}","handlingStrategy":"validation","validationCode":"function validateOrgKeyPayload({armored_key, fingerprint}) {\n  if (!armored_key?.includes('-----BEGIN PGP PUBLIC KEY BLOCK-----')) return 'armor';\n  if (!/^[0-9A-F]{40}$/.test(fingerprint)) return 'fingerprint';\n  return null;\n}","typeGuard":"function isWellFormedOrgKeyPayload(p) {\n  return typeof p.armored_key === 'string'\n    && p.armored_key.includes('BEGIN PGP PUBLIC KEY BLOCK')\n    && /^[0-9A-F]{40}$/.test(p.fingerprint);\n}","tryCatchPattern":"try {\n  await api.setOrganizationPolicy(payload);\n} catch (e) {\n  const nested = e.body?.errors?.account_recovery_organization_public_key;\n  // nested mirrors the inner ValidationException errors; log and fix per field\n  console.error(nested);\n}","preventionTips":["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"],"tags":["openpgp","account-recovery","validation","wrapper-error"],"backgroundTag":"schema-validation-failed","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}