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

  1. Verify the metadata key id exists and has rows in metadata_private_keys (query the table directly)
  2. Re-generate or restore the metadata private key for the affected key (e.g. via metadata key creation/rotation flow)
  3. Ensure the metadata_private_keys data was migrated when moving between instances
  4. 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

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


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)