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 encrypt. 

What it means

Thrown by setEncryptKeyWithServerKey when the GnuPG backend cannot set the configured server key as encryption key, even after re-importing the server key into the keyring. It wraps the underlying exception message from gnupg (import or setEncryptKeyFromFingerprint failure). It signals a server-side OpenPGP configuration/keyring problem, not a user-facing input error.

Solutions

  1. Verify the configured key exists and the fingerprint matches: compare `passbolt.gpg.serverKey.fingerprint` with the output of `gpg --show-keys <path to serverkey.asc>` (run as the web server user).
  2. Import the key manually into the web-user keyring: `sudo -H -u www-data gpg --home /var/lib/passbolt/.gnupg --import /etc/passbolt/serverkey.asc`, then retry.
  3. Check GNUPGHOME permissions: the keyring directory and its files must be owned and writable by the web server user (chmod 700 on the dir).
  4. Confirm the key is not expired/revoked and has the encryption capability (usage flag E); regenerate with `passbolt recover_user` style tooling or `gpg --quick-gen-key` if needed.
  5. Read the appended $exception->getMessage() in the 500 response/logs — it names the exact gnupg failure (e.g. 'get key failed', 'import failed').

Example fix

// before (config/app.php)
'fingerprint' => '0FC9E3A4FA0C08A79B8E1F4B57D5F0B200A8ABF7', // stale fingerprint
// after
'fingerprint' => '<fingerprint printed by: gpg --show-keys /etc/passbolt/serverkey.asc>',
Defensive patterns

Strategy: try-catch

Validate before calling

// Run before requests / in a healthcheck
$fp = Configure::read('passbolt.gpg.serverKey.fingerprint');
$home = Configure::read('passbolt.gpg.serverKey.fingerprint');
exec(sprintf('sudo -H -u www-data gpg --list-keys %s 2>/dev/null', escapeshellarg($fp)), $out, $code);
if (!PublicKeyValidationService::isValidFingerprint($fp) || $code !== 0) {
    throw new Exception('Server key missing from keyring or fingerprint invalid');
}

Type guard

function isValidServerKeyFingerprint(mixed $fp): bool
{
    return is_string($fp) && PublicKeyValidationService::isValidFingerprint($fp);
}

Try / catch

try {
    $gpg = $this->setEncryptKeyWithServerKey($gpg);
} catch (InternalErrorException $e) {
    Log::error('Server key encrypt setup failed: ' . $e->getMessage());
    throw new InternalErrorException('Server OpenPGP key is not operational; run the key import healthcheck.');
}

Prevention

When it happens

Trigger: Calling setEncryptKeyWithServerKey when: the key file at passbolt.gpg.serverKey.path does not exist or is unreadable; the fingerprint in config does not match the actual key; the keyring (GNUPGHOME) is not writable by the web server user; the key is expired/revoked or lacks encryption capability; gnupg extension cannot access the keyring.

Common situations: Fresh passbolt install where serverkey.asc was never imported into the web user's keyring; changing GNUPGHOME or running CLI commands as a different user (root vs www-data) so the keyring diverges; incorrect passbolt.gpg.serverKey.fingerprint after replacing the server key; wrong filesystem permissions on ~/.gnupg after a container/package upgrade.

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/ddad5c4ad92d1bb8. Report an issue: GitHub.

Appendix: source

Thrown at src/Service/OpenPGP/OpenPGPCommonServerOperationsTrait.php:51

        // Check if config contains fingerprint
        $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');
        $this->assertServerFingerprint($fingerprint);

        // Check if config contains valid passphrase
        $passphrase = Configure::read('passbolt.gpg.serverKey.passphrase');
        $this->assertServerPassphrase($passphrase);

        // set the key to be used for encrypting
        try {
            $gpg->setEncryptKeyFromFingerprint($fingerprint);
        } catch (Exception $exception) {
            try {
                $gpg->importServerKeyInKeyring();
                $gpg->setEncryptKeyFromFingerprint($fingerprint);
            } catch (Exception $exception) {
                $msg = __('The OpenPGP server key defined in the config cannot be used to encrypt.') . ' ';
                $msg .= $exception->getMessage();
                throw new InternalErrorException($msg, 500, $exception);
            }
        }

        return $gpg;
    }

    /**
     * @param \App\Utility\OpenPGP\OpenPGPBackend $gpg for example OpenPGPBackendFactory::get()
     * @return \App\Utility\OpenPGP\OpenPGPBackend backend configured to use server key to sign
     * @throws \Cake\Http\Exception\InternalErrorException if the server key cannot be loaded
     */
    public function setDecryptKeyWithServerKey(OpenPGPBackend $gpg): OpenPGPBackend
    {
        // Check if config contains fingerprint
        $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');
        $this->assertServerFingerprint($fingerprint);

        // Check if config contains valid passphrase

View on GitHub (pinned to 31c1bbc10f)