passbolt/passbolt_api · error · InternalErrorException
The metadata private key cleartext data is not valid.
Error message
The metadata private key cleartext data is not valid.
What it means
assertPrivateKey throws InternalErrorException when the decoded cleartext array fails validation by MetadataCleartextPrivateKeyForm. The data is valid non-empty JSON but missing required fields (e.g. objectType, armored_key) or violating the form's schema for a metadata private key cleartext.
Solutions
- Enable debug to see json_encode($form->getErrors()) and identify which fields fail
- Compare the cleartext against the MetadataCleartextPrivateKeyForm schema and fix missing/invalid fields (objectType, armored_key, etc.)
- Re-import or regenerate the metadata private key using the official passbolt migration tooling/commands rather than custom scripts
- Ensure all plugins are upgraded together so the cleartext schema version matches what the server expects
Example fix
// before: incomplete cleartext
{"armored_key": "-----BEGIN PGP PRIVATE KEY BLOCK-----..."}
// after: schema-conformant cleartext
{"objectType": "PASSBOLT_METADATA_PRIVATE_KEY", "armored_key": "-----BEGIN PGP PRIVATE KEY BLOCK-----...", "created": "2024-01-01T00:00:00+00:00", "modified": "2024-01-01T00:00:00+00:00"} Defensive patterns
Strategy: validation
Validate before calling
$decoded = json_decode($cleartext, true, 2);
$form = new \Passbolt\Metadata\Form\MetadataCleartextPrivateKeyForm();
if (!is_array($decoded) || !$form->validate($decoded)) {
throw new \DomainException('Cleartext schema invalid: ' . json_encode($form->getErrors()));
} Type guard
function passesCleartextForm(array $decoded): bool {
return isset($decoded['objectType'], $decoded['armored_key'])
&& $decoded['objectType'] === 'PASSBOLT_METADATA_PRIVATE_KEY'
&& is_string($decoded['armored_key']);
} Try / catch
try {
$service->shareMetadataKeysWithUser($uac, $userIds, $keyId);
} catch (MetadataKeyShareException $e) {
if (str_contains($e->getMessage(), 'cleartext data is not valid')) {
// inspect MetadataCleartextPrivateKeyForm errors in debug logs and re-import conformant data
}
} Prevention
- Generate cleartext envelopes only via passbolt's official forms/DTOs, never hand-rolled arrays
- Use the official migration commands (e.g. metadata key migration shell) instead of ad-hoc scripts
- Pin client and server to compatible plugin versions when importing keys
- Run assertPrivateKey-equivalent validation as a pre-import check
When it happens
Trigger: shareMetadataKeyWithUser decrypts the server copy and validates the cleartext structure; a payload missing keys like 'objectType' => 'PASSBOLT_METADATA_PRIVATE_KEY' or a valid 'armored_key', or with extra/invalid fields, fails $form->validate($decoded) and raises this error (form errors logged in debug).
Common situations: Keys imported by tooling that produced a slightly different JSON shape; passbolt version mismatch where the cleartext schema changed; hand-crafted migration/import scripts that omitted required properties.
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 validate metadata key data.
- Could not validate the metadata key data for the entity…
- The metadata could not be encrypted with the metadata key…
- The data entered are not correct
- The data entered are not correct
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/d1075aaa823e2272.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/Metadata/src/Service/MetadataKeyShareDefaultService.php:187
} catch (Exception $exception) {
if (Configure::read('debug')) {
Log::error($clearText);
}
$msg = __('The metadata private key cleartext data should be in JSON format.');
throw new InternalErrorException($msg, 500, $exception);
}
if (!is_array($decoded) || empty($decoded)) {
$msg = __('The metadata private key cleartext data should not be empty.');
throw new InternalErrorException($msg);
}
$form = new MetadataCleartextPrivateKeyForm();
if (!$form->validate($decoded)) {
if (Configure::read('debug')) {
Log::error(json_encode($form->getErrors()));
}
$msg = __('The metadata private key cleartext data is not valid.');
throw new InternalErrorException($msg);
}
}
/**
* Get the OpenPGP Backend ready to decrypt with server key
*
* @param \App\Utility\OpenPGP\OpenPGPBackend $gpg for example OpenPGPBackendFactory::get()
* @param string|null $createdBy uuid of user
* @return \App\Utility\OpenPGP\OpenPGPBackend backend configured to use server keys
* @throws \Cake\Http\Exception\InternalErrorException if the server key cannot be loaded
*/
private function setKeyForVerify(OpenPGPBackend $gpg, ?string $createdBy = null): OpenPGPBackend
{
// Use server key if no user is defined in createdBy
if ($createdBy === null) {
return $this->setVerifyKeyWithServerKey($gpg);
}
View on GitHub (pinned to 31c1bbc10f)