{"record":{"id":"0e2934352a1425ff","repo":"passbolt/passbolt_api","slug":"could-not-validate-public-key-data","errorCode":null,"errorMessage":"Could not validate public key data.","messagePattern":"Could not validate public key data\\.","errorType":"validation","errorClass":"ValidationException","httpStatus":422,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Model/Table/AccountRecoveryOrganizationPublicKeysTable.php","lineNumber":202,"sourceCode":"     * @throws \\App\\Error\\Exception\\ValidationException if entity validation fails\n     * @return \\Passbolt\\AccountRecovery\\Model\\Entity\\AccountRecoveryOrganizationPublicKey\n     */\n    public function buildAndValidateEntity(UserAccessControl $uac, array $data): AccountRecoveryOrganizationPublicKey\n    {\n        $data['created_by'] = $uac->getId();\n        $data['modified_by'] = $uac->getId();\n\n        $publicKey = $this->newEntity($data, [\n            'accessibleFields' => [\n                'fingerprint' => true,\n                'armored_key' => true,\n                'created_by' => true,\n                'modified_by' => true,\n            ],\n        ]);\n\n        if ($publicKey->getErrors()) {\n            throw new ValidationException(__('Could not validate public key data.'), $publicKey, $this);\n        }\n\n        return $publicKey;\n    }\n\n    /**\n     * Format fingerprint data to remove spaces and set it to uppercase\n     *\n     * @param \\Cake\\Event\\EventInterface $event event\n     * @param \\ArrayObject $data user provided data\n     * @param \\ArrayObject $options options\n     * @return void\n     */\n    public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options): void\n    {\n        if (isset($data['fingerprint']) && is_string($data['fingerprint'])) {\n            $data['fingerprint'] = strtoupper(str_replace(' ', '', $data['fingerprint']));\n        }","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Model/Table/AccountRecoveryOrganizationPublicKeysTable.php#L184-L220","documentation":"A ValidationException thrown when the organization public key entity built in buildAndValidateEntity fails the table's validation rules (e.g. malformed armored key, missing fingerprint/fields). The failing entity is attached to the exception for field-level inspection.","triggerScenarios":"Saving an organization recovery public key with an invalid OpenPGP armored key, missing required fields (armored_key, fingerprint), or data not matching column constraints.","commonSituations":"Client generates a key with an unsupported algorithm; armored key truncated or re-formatted (line endings) by intermediate code; copy-paste losing header/footer lines.","solutions":["Inspect entity errors attached to the ValidationException.","Regenerate the organization key with a supported algorithm and full ASCII-armor output.","Ensure the armored_key includes complete BEGIN/END PGP blocks and valid fingerprint.","Check for encoding/line-ending mangling when transmitting the key."],"exampleFix":"// before\n\"armored_key\": \"-----BEGIN PGP PUBLIC KEY BLOCK-----\" // truncated\n// after\n\"armored_key\": \"-----BEGIN PGP PUBLIC KEY BLOCK-----\\n...\\n-----END PGP PUBLIC KEY BLOCK-----\"","handlingStrategy":"validation","validationCode":"if (!key.armored_key?.includes('-----END PGP PUBLIC KEY BLOCK-----')) throw new Error('armored key incomplete');\nif (!/^[A-F0-9]{40}$/i.test(key.fingerprint)) throw new Error('invalid fingerprint');","typeGuard":"function isArmoredPublicKey(v) { return typeof v === 'string' && v.includes('-----BEGIN PGP PUBLIC KEY BLOCK-----') && v.includes('-----END PGP PUBLIC KEY BLOCK-----'); }","tryCatchPattern":"try { await api.saveOrganizationPublicKey(key); } catch (e) { if (e.body && e.body.account_recovery_organization_public_key) { reportFieldErrors(e.body.account_recovery_organization_public_key); } else { throw e; } }","preventionTips":["Validate armor completeness (BEGIN/END lines) before upload.","Generate keys with OpenPGP.js versions matching the server.","Avoid text-mode transformations that alter line endings.","Check the fingerprint is 40 hex characters."],"tags":["validation","pgp","account-recovery","public-key"],"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"}