passbolt/passbolt_api · critical · InternalErrorException

500

500

Error message

{exceptionMessage} The metadata could not be encrypted with the metadata key id: {0}.

What it means

When migrating a shared tag, the service encrypts the cleartext metadata with the metadata key. Any failure inside the encryption block (GPG operation error, missing/unusable metadata key, JSON encoding failure) is wrapped into an InternalErrorException whose message prefixes the original exception message and names the metadata key id.

Solutions

  1. Verify a valid metadata key exists and the server can decrypt/sign with it (check metadata_keys table and key storage).
  2. Confirm GnuPG works server-side (gnupg home directory permissions, agent running).
  3. Inspect the wrapped original exception message (prefixed in the error) for the root cause.
  4. Re-run the migration after restoring the key; the failing tag remains V4 and can be retried.
Defensive patterns

Strategy: try-catch

Validate before calling

$metadataKey = $this->MetadataKeys->getLatestNonExpiredKey();
if (!$metadataKey || !$metadataKey->hasValidPrivateKey()) {
    throw new \RuntimeException('No usable metadata key; abort migration');
}

Type guard

function canEncryptWithKey(?MetadataKey $key): bool {
    return $key !== null && !$key->expired && $key->deleted === null;
}

Try / catch

try {
    $service->migrate($uac, $batch);
} catch (InternalErrorException $e) {
    $this->log('Shared tag encryption failed: ' . $e->getMessage(), 'error');
    // resume batch after key/GPG repair; failed tags remain V4
}

Prevention

When it happens

Trigger: Metadata key missing, deleted, expired, or its private key material unavailable on the server during shared-tag migration; GnuPG backend failure while encrypting; json_encode throwing on malformed metadata arrays.

Common situations: Server without the metadata private key passphrase configured; metadata key rotated and old key revoked before migration; GnuPG keyring/agent issues in containerized environments.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/88d9722ce3312e4d. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/Tags/src/Service/Metadata/MigrateAllV4TagsToV5Service.php:177

     * @return void
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When there is no metadata key record.
     */
    private function migrateShared(MetadataTagDto $dto, Tag $tag): void
    {
        $metadataArray = $dto->getClearTextMetadata();
        $metadataKey = $this->getMetadataKeyForEncryption();

        try {
            $gpg = OpenPGPBackendFactory::get();
            $gpg->clearKeys();
            $gpg = $this->setSignKeyWithServerKey($gpg);
            $gpg = $this->setEncryptKeyWithMetadataKey($gpg, $metadataKey);
            $metadataClearText = json_encode($metadataArray, JSON_THROW_ON_ERROR);
            $metadataEncrypted = $gpg->encrypt($metadataClearText, true);
        } catch (Exception $exception) {
            $msg = $exception->getMessage() . ' ';
            $msg .= __('The metadata could not be encrypted with the metadata key id: {0}.', $metadataKey->id);
            throw new InternalErrorException($msg, 500, $exception);
        }

        $this->updateTag($tag, [
            'slug' => null,
            'metadata' => $metadataEncrypted,
            'metadata_key_id' => $metadataKey->id,
            'metadata_key_type' => MetadataKey::TYPE_SHARED_KEY,
            'is_shared' => true,
        ]);
    }

    /**
     * @param \Passbolt\Tags\Model\Dto\MetadataTagDto $dto DTO.
     * @param \Passbolt\Tags\Model\Entity\Tag $tag Tag entity.
     * @return void
     */
    private function migratePersonal(MetadataTagDto $dto, Tag $tag): void
    {

View on GitHub (pinned to 31c1bbc10f)