{"record":{"id":"dc2e1e6904097d8a","repo":"passbolt/passbolt_api","slug":"could-not-validate-private-key-data","errorCode":null,"errorMessage":"Could not validate private key data.","messagePattern":"Could not validate private key data\\.","errorType":"validation","errorClass":"CustomValidationException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryUserSettings/AccountRecoveryUserSettingsSetService.php","lineNumber":226,"sourceCode":"        try {\n            // Entity validation &\n            $privateKeyEntity = $this->AccountRecoveryPrivateKeys->buildAndValidateEntity($this->uac, $data);\n\n            // Validate private key OpenPGP message &\n            $rules = MessageValidationService::getSymmetricMessageRules();\n            MessageValidationService::parseAndValidateMessage($privateKeyEntity->data, $rules);\n\n            // Validate business rules\n            if (!$this->AccountRecoveryPrivateKeys->checkRules($privateKeyEntity)) {\n                $errors = $privateKeyEntity->getErrors();\n            }\n        } catch (CustomValidationException | ValidationException $exception) {\n            $errors = $exception->getErrors();\n        }\n\n        if (isset($errors) || !isset($privateKeyEntity)) {\n            $msg = __('Could not validate private key data.');\n            throw new CustomValidationException($msg, [\n                'account_recovery_user_setting' => [\n                    'account_recovery_private_key' => $errors ?? [],\n                ],\n            ]);\n        }\n\n        return $privateKeyEntity;\n    }\n\n    /**\n     * @return array<\\Passbolt\\AccountRecovery\\Model\\Entity\\AccountRecoveryPrivateKeyPassword> array of AccountRecoveryPrivateKeyPasswords\n     */\n    public function buildPasswordEntitiesFromDataOrFail(): array\n    {\n        $passwordsData = $this->data['account_recovery_private_key']['account_recovery_private_key_passwords'] ?? [];\n        try {\n            $service = new AccountRecoveryPrivateKeyPasswordsValidationService();\n            $publicKey = $this->organizationPolicy->account_recovery_organization_public_key->armored_key;","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryUserSettings/AccountRecoveryUserSettingsSetService.php#L208-L244","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the nested errors in the response for the exact failing rule","Ensure a valid openpgp armored PRIVATE key is submitted, complete with armor headers","Verify the key matches the user's account key and the passwords decrypt it","Validate the armored key client-side (openpgp.js) before sending"],"exampleFix":"// before\nprivateKey: user.publicArmoredKey\n// after\nprivateKey: user.privateArmoredKey // decrypted/validated locally first","handlingStrategy":"validation","validationCode":"const key = await openpgp.readKey({armoredKey}); if (key.isPublic() || key.isPrivate() === false) throw new Error('a private key is required');","typeGuard":"const isArmoredPrivateKey = (s) => typeof s === 'string' && s.includes('-----BEGIN PGP PRIVATE KEY BLOCK-----');","tryCatchPattern":"try { await setSettings(data); } catch (e) { const errs = e.body?.account_recovery_user_setting?.account_recovery_private_key; if (errs) showKeyErrors(errs); }","preventionTips":["Validate the armored key with openpgp.js before submitting","Confirm the key is private and matches the user's key","Beware copy/paste truncation of armor blocks"],"tags":["validation","pgp","private-key"],"backgroundTag":"invalid-argument-value","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"}