passbolt/passbolt_api · error · InternalErrorException

The metadata could not be encrypted with the user id: .

Error message

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

What it means

The actual OpenPGP encryption step of migratePersonal failed: any exception from OpenPGPBackendFactory setup, key loading, JSON encoding, or gpg->encrypt() is re-thrown as an InternalErrorException prefixed with the original exception message and suffixed with the user ID. It wraps the previous exception for the logs.

Solutions

  1. Read the chained exception / the prefixed exceptionMessage to identify the actual GPG failure.
  2. Verify the server OpenPGP key is present and loadable (setSignKeyWithServerKey) and GNUPGHOME permissions are correct.
  3. Check the user's public key is valid, not expired/revoked, and supported by the gpg binary version.
  4. Confirm the php gnupg/openpgp backend is installed and the gpg binary is available to the PHP process.

Example fix

// before
$metadataEncrypted = $gpg->encrypt($metadataClearText, true);
// after: harden against missing server key
$gpg = OpenPGPBackendFactory::get();
$gpg->clearKeys();
$serverKeyInfo = Configure::read('passbolt.gpg.serverKey');
if (!file_exists($serverKeyInfo['fingerprint'] ? $serverKeyInfo['public'] : '')) {
    throw new InternalErrorException('Server OpenPGP key not found.');
}
$gpg = $this->setSignKeyWithServerKey($gpg);
$metadataEncrypted = $gpg->encrypt($metadataClearText, true);
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight the GPG environment before migrating
$gpg = OpenPGPBackendFactory::get();
$gpg->clearKeys();
$gpg->importKeyIntoKeyring(Filesystem::read(Configure::read('passbolt.gpg.serverKey.public')));
// and confirm each target user's key is present, non-expired, non-revoked

Try / catch

try {
    $service->migrate($uac);
} catch (\Cake\Http\Exception\InternalErrorException $e) {
    error_log($e->getPrevious()?->getMessage() ?? $e->getMessage());
    // fix gnupg keyring / server key / user key per root cause, then retry
}

Prevention

When it happens

Trigger: Calling migrate → migratePersonal when the GnuPG backend fails: server key not loaded/found, user's public key corrupt or unsupported algorithm, gpg binary missing, or json_encode throwing (JSON_THROW_ON_ERROR) on malformed metadata.

Common situations: GNUPGHOME misconfigured or not writable by web user; gnupg extension absent; expired/revoked user key; server OpenPGP key missing from keyring; non-UTF8 folder names breaking JSON encoding.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltCe/Metadata/src/Service/Migration/MigrateAllV4FoldersToV5Service.php:171

            throw new InternalErrorException($msg);
        }
        if (is_null($user->gpgkey)) {
            $msg = __('No OpenPGP key found for the user.') . ' ';
            $msg .= __('The metadata could not be encrypted with the user id: {0}.', $user->id);
            throw new InternalErrorException($msg);
        }

        try {
            $gpg = OpenPGPBackendFactory::get();
            $gpg->clearKeys();
            $gpg = $this->setSignKeyWithServerKey($gpg);
            $gpg = $this->setEncryptKeyWithUserKey($gpg, $user->gpgkey);
            $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 user id: {0}.', $user->id);
            throw new InternalErrorException($msg, 500, $exception);
        }

        $this->updateFolder($folder, [
            'name' => null,
            'metadata' => $metadataEncrypted,
            'metadata_key_id' => $user->gpgkey->id,
            'metadata_key_type' => 'user_key',
        ]);
    }

    /**
     * @param \Passbolt\Metadata\Model\Dto\MetadataFolderDto $dto DTO.
     * @param \Passbolt\Folders\Model\Entity\Folder $folder Entity.
     * @return void
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When there is no metadata key record.
     */
    private function migrateShared(MetadataFolderDto $dto, Folder $folder): void
    {

View on GitHub (pinned to 31c1bbc10f)