passbolt/passbolt_api · error · NotFoundException
Missing metadata private key.
Error message
Missing metadata private key.
What it means
Thrown by ShareMetadataKeyCommand::findMetadataPrivateKey() when the metadata key identified by $missingMetadataKeyId has no associated metadata_private_keys entry in the fetched $metadataKeys array. The command cannot share a metadata key with users without its private key material, so it aborts with a 404-style NotFoundException.
Solutions
- Verify the metadata key id exists and has rows in metadata_private_keys (query the table directly)
- Re-generate or restore the metadata private key for the affected key (e.g. via metadata key creation/rotation flow)
- Ensure the metadata_private_keys data was migrated when moving between instances
- Double-check the key id passed on the command line matches an existing metadata_keys.id
Example fix
// before bin/cake passbolt share_metadata_key 0a1b... # key has no private key row -> 404 // after # check first SELECT metadata_key_id FROM metadata_private_keys WHERE metadata_key_id = '0a1b...'; # if empty, recreate the key or restore its private key before sharing
Defensive patterns
Strategy: validation
Validate before calling
$key = $metadataKeysTable->find()
->where(['id' => $metadataKeyId])
->contain('MetadataPrivateKeys')
->first();
if (!$key || empty($key->metadata_private_keys)) {
throw new \Cake\Http\Exception\NotFoundException('No private key for metadata key ' . $metadataKeyId);
} Type guard
function hasMetadataPrivateKey(?array $metadataKeys, string $keyId): bool {
return isset($metadataKeys[$keyId]['metadata_private_keys'][0]);
} Try / catch
try {
$this->executeCommand(ShareMetadataKeyCommand::class, [$metadataKeyId]);
} catch (\Cake\Http\Exception\NotFoundException $e) {
$io->error('Restore the metadata private key for ' . $metadataKeyId . ' first.');
} Prevention
- Verify metadata_private_keys rows survived instance migrations
- Validate the key id exists before running the share command
- Monitor metadata key creation flows for partial failures
- Keep backups of metadata_private_keys data
When it happens
Trigger: Running `passbolt share_metadata_key` when the targeted metadata key id has zero MetadataPrivateKey rows (key generated without the server's private-key share), or the id passed does not exist in the collected $metadataKeys array.
Common situations: Metadata keys migrated from another instance without copying metadata_private_keys, partially failed metadata key creation leaving the key without private-key rows, and mistyped metadata key IDs on the command line.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Could not read the file
- $e->getMessage()
- The file does not exist
- The metadata key has already been deleted.
- The metadata private key does not exist or has been deleted.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/a45b105db1b178ba.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/Metadata/src/Command/ShareMetadataKeyCommand.php:204
continue;
}
$this->success(
__('The metadata key {0} was shared with user {1}.', $missingMetadataKeyId, $user->username),
$io
);
}
}
/**
* @param string $missingMetadataKeyId Metadata key id to find.
* @param array $metadataKeys Metadata keys.
* @return \Passbolt\Metadata\Model\Entity\MetadataPrivateKey
*/
private function findMetadataPrivateKey(string $missingMetadataKeyId, array $metadataKeys): MetadataPrivateKey
{
if (empty($metadataKeys[$missingMetadataKeyId]['metadata_private_keys'])) {
throw new NotFoundException(__('Missing metadata private key.', $missingMetadataKeyId));
}
return $metadataKeys[$missingMetadataKeyId]['metadata_private_keys'][0];
}
}
View on GitHub (pinned to 31c1bbc10f)