passbolt/passbolt_api · critical · InternalErrorException
The OpenPGP server key defined in the config cannot be used…
Error message
The OpenPGP server key defined in the config cannot be used to decrypt.
What it means
decrypt() sets up OpenPGP with the server key from configuration and calls importServerKeyInKeyring()/setDecryptKeyFromFingerprint(). If either fails (key missing from config, unreadable key file, wrong passphrase, keyring problems), it wraps the underlying exception into an InternalErrorException starting with 'The OpenPGP server key defined in the config cannot be used to decrypt.'
Solutions
- Verify config pass.serverKey fingerprint matches the actual server key and the key file exists and is readable.
- Check the key passphrase in config matches the key; fix or remove an incorrect passphrase.
- Ensure the GPG keyring directory (GNUPGHOME / WEBROOT_TMP) exists and is writable by the web server user.
- Import the server key manually (gpg --import) and re-test; read the appended exception message for the gnupg failure cause.
- Run bin/cake passbolt healthcheck for GPG configuration checks.
Example fix
// before (config/app.php) 'serverKey' => ['fingerprint' => '<OLD_FINGERPRINT>', 'passphrase' => ''] // after 'serverKey' => ['fingerprint' => '<CORRECT_FINGERPRINT_FROM_serverkey.asc>', 'passphrase' => '<CORRECT_PASSPHRASE>']
Defensive patterns
Strategy: try-catch
Validate before calling
// check config before calling
$fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');
$passphrase = Configure::read('passbolt.gpg.serverKey.passphrase');
if (empty($fingerprint)) { throw new Exception('Missing server key fingerprint'); } Try / catch
try { $dto = $service->getByIdOrFail($id, true); } catch (InternalErrorException $e) { if (str_contains($e->getMessage(), 'server key')) { // alert: check GPG config/keyring } } Prevention
- Run bin/cake passbolt healthcheck after any server/config change
- Keep the server key fingerprint, private key and passphrase in sync in config
- Ensure the GPG keyring directory is owned by the web user and persists across deploys
- Copy the server key when migrating hosts
When it happens
Trigger: The server OpenPGP key fingerprint in config is wrong or the key is not present in the filesystem; the key passphrase is missing/incorrect; the GPG keyring is not writable or gnupg extension fails to import the key.
Common situations: Migration to a new server where the server key was not copied; config/app.php pass.serverKey pointing to a stale fingerprint; wrong file permissions on the keyring directory; GPG homedir misconfigured in the container.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- The OpenPGP server key defined in the config cannot be used…
- The OpenPGP server key defined in the config cannot be used…
- The SCIM settings could not be decrypted with the server…
- The SSO setting cannot be decrypted.
- Invalid request, message validation rules are missing.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/55f4b6fc67fa3613.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Service/SsoSettings/SsoSettingsGetService.php:159
* @throws \Cake\Http\Exception\InternalErrorException if there is an issue with settings data decryption
* @return array
*/
protected function decrypt(string $data): array
{
$gpg = OpenPGPBackendFactory::get();
$fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');
$passphrase = Configure::read('passbolt.gpg.serverKey.passphrase');
try {
$gpg->setDecryptKeyFromFingerprint($fingerprint, $passphrase);
} catch (Exception $exception) {
try {
$gpg->importServerKeyInKeyring();
$gpg->setDecryptKeyFromFingerprint($fingerprint, $passphrase);
} catch (Exception $exception) {
$msg = __('The OpenPGP server key defined in the config cannot be used to decrypt.') . ' ';
$msg .= $exception->getMessage();
throw new InternalErrorException($msg, 500, $exception);
}
}
try {
$decryptedData = $gpg->decrypt($data);
} catch (Exception $exception) {
throw new InternalErrorException(__('The SSO setting cannot be decrypted.'), 500, $exception);
}
$decodedData = json_decode($decryptedData, true);
if (!isset($decodedData) || !is_array($decodedData)) {
throw new InternalErrorException(__('The SSO setting cannot be decoded.'));
}
return $decodedData;
}
}
View on GitHub (pinned to 31c1bbc10f)