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
- Read the chained exception / the prefixed exceptionMessage to identify the actual GPG failure.
- Verify the server OpenPGP key is present and loadable (setSignKeyWithServerKey) and GNUPGHOME permissions are correct.
- Check the user's public key is valid, not expired/revoked, and supported by the gpg binary version.
- 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
- Verify GNUPGHOME exists and is writable by the PHP user before migrations
- Ensure the server OpenPGP key pair is configured and importable
- Keep the gpg binary and PHP gnupg extension installed and version-compatible
- Test encryption with one folder before batch-migrating
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
- Could not use the key to encrypt.
- The metadata could not be encrypted with the metadata key…
- The metadata could not be encrypted with the user id: .
- No OpenPGP key found for the user. The metadata could not…
- No OpenPGP key found for the user. The metadata could not…
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)