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

Thrown by SmtpSettingsGetSettingsInDbService::decrypt when the OpenPGP server key configured via passbolt.gpg.serverKey cannot be loaded into the keyring or set as the decryption key. Passbolt encrypts SMTP settings with the server key before storing them in organization_settings; if the key import or setDecryptKeyFromFingerprint fails, no decryption key exists and the read fails with an HTTP 500 InternalErrorException whose message includes the underlying GnuPG error.

Solutions

  1. Restore the original server OpenPGP key files and make sure passbolt.gpg.serverKey.fingerprint, .public and .private in config point to them, then re-run the request
  2. Run `su -s /bin/bash -c "gpg --home /var/lib/passbolt/.gnupg --list-keys" <webserver-user>` (or inspect GNUPGHOME) to verify the key with the configured fingerprint exists in the keyring; re-import it with `passbolt import_private_key` / gpg --import if missing
  3. Check the passphrase in passbolt.gpg.serverKey.passphrase matches the key's passphrase; fix and clear cache (`rm -f tmp/cache/*`)
  4. Fix filesystem permissions on the key files and the gnupg home so the web server user can read/write them (chmod 700 ~/.gnupg, chown webserver-user)
  5. As a last resort, re-configure the SMTP settings via the UI/`passbolt send_test_email` so they are re-encrypted with the current server key

Example fix

// before (config/passbolt.php)
'fingerprint' => 'ABCOLD123...',
'public' => CONFIG . 'gpg' . DS . 'serverkey.asc',
// after
'fingerprint' => sha1(file_get_contents(CONFIG . 'gpg' . DS . 'serverkey_private.asc')), // must match imported key
'public' => CONFIG . 'gpg' . DS . 'serverkey.asc',
'private' => CONFIG . 'gpg' . DS . 'serverkey_private.asc', // and ensure the key file is copied to the new host
Defensive patterns

Strategy: try-catch

Validate before calling

$fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');
$home = getenv('GNUPGHOME') ?: (Configure::read('passbolt.gpg.keyring') ?? '~/.gnupg');
$output = shell_exec("gpg --homedir $home --list-keys $fingerprint 2>/dev/null");
if (!$output) { throw new \RuntimeException('Server key not in keyring: ' . $fingerprint); }

Type guard

function serverKeyIsUsable(array $gpgConfig): bool
{
    return !empty($gpgConfig['fingerprint'])
        && is_readable($gpgConfig['public'] ?? '')
        && is_readable($gpgConfig['private'] ?? '');
}

Try / catch

try {
    $settings = (new SmtpSettingsGetSettingsInDbService())->getSettings();
} catch (\Cake\Http\Exception\InternalErrorException $e) {
    $this->log('SMTP settings decryption failed: ' . $e->getMessage(), 'error');
    $settings = Configure::read('passbolt.emailTransports.smtp'); // fallback to file config
}

Prevention

When it happens

Trigger: Any code path that reads SMTP settings from the DB (readConfigInDB -> decrypt), e.g. GET /smtp/settings or sending a test email, when the configured server key fingerprint does not match a key present/importable in the GPG keyring, the key file defined in passbolt.gpg.serverKey.public/private is missing or unreadable, or the passphrase in the config is wrong.

Common situations: Migrating passbolt to a new server without copying the server OpenPGP keys; changing the fingerprint in passbolt.php or the environment after settings were already encrypted; gnupg home directory (GNUPGHOME) permission problems after running the app as a different user; rotating the server key; Docker volume not mounting the key files.

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


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

Appendix: source

Thrown at plugins/PassboltCe/SmtpSettings/src/Service/SmtpSettingsGetSettingsInDbService.php:118

     * @throw InternalErrorException If the smtp settings cannot be decrypted
     */
    protected function decrypt(string $encryptedValue): string
    {
        $keyFingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');
        $passphrase = Configure::read('passbolt.gpg.serverKey.passphrase');
        $gpg = OpenPGPBackendFactory::get();

        // set the key to be used for decrypting
        try {
            $gpg->setDecryptKeyFromFingerprint($keyFingerprint, $passphrase);
        } catch (CakeException $exception) {
            try {
                $gpg->importServerKeyInKeyring();
                $gpg->setDecryptKeyFromFingerprint($keyFingerprint, $passphrase);
            } catch (CakeException $exception) {
                $msg = __('The OpenPGP server key defined in the config cannot be used to decrypt.') . ' ';
                $msg .= $exception->getMessage();
                throw new InternalErrorException($msg);
            }
        }

        try {
            return $gpg->decrypt($encryptedValue);
        } catch (Throwable $e) {
            $msg = __('The OpenPGP server key cannot be used to decrypt the SMTP settings stored in database.');
            $msg .= ' ' . __('To fix this problem, you need to configure the SMTP server again.') . ' ';
            $msg .= $e->getMessage();
            throw new InternalErrorException($msg, 500, $e);
        }
    }
}

View on GitHub (pinned to 31c1bbc10f)