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 verify signature. 

What it means

Thrown by setVerifyKeyWithServerKey when the GnuPG backend cannot set the configured server key as signature-verification key, even after importing it into the keyring. The wrapped gnupg message is appended. Typically means the key used to verify server-signed tokens/responses cannot be resolved from the keyring by the configured fingerprint.

Solutions

  1. Compare `passbolt.gpg.serverKey.fingerprint` against `gpg --show-keys <serverKey.path>` — fix any mismatch or whitespace.
  2. Ensure passbolt.gpg.serverKey.path points to an existing, readable public key file and that `public` config is true if serving it.
  3. Import manually as the web server user: `sudo -H -u www-data gpg --home <gnupghome> --import /etc/passbolt/serverkey.asc`, then retry the request.
  4. Fix GNUPGHOME permissions (owned by web user, mode 700) so the import into the keyring can succeed.
  5. Check the appended exception message for the precise gnupg error (e.g. 'import failed – invalid key').

Example fix

// before
'serverKey' => ['fingerprint' => trim(file_get_contents('/etc/passbolt/fingerprint'))], // trailing newline
// after
'serverKey' => ['fingerprint' => strtoupper(preg_replace('/\s+/', '', $rawFingerprint))],
Defensive patterns

Strategy: validation

Validate before calling

$fp = preg_replace('/\s+/', '', (string)Configure::read('passbolt.gpg.serverKey.fingerprint'));
if (!PublicKeyValidationService::isValidFingerprint($fp)) {
    throw new Exception('passbolt.gpg.serverKey.fingerprint missing or malformed');
}
$path = Configure::read('passbolt.gpg.serverKey.path');
if (!is_readable($path)) {
    throw new Exception("Server key file not readable: {$path}");
}
exec('gpg --show-keys ' . escapeshellarg($path) . ' 2>/dev/null', $out, $code);
if ($code !== 0 || strpos(implode('\n', $out), strtoupper($fp)) === false) {
    throw new Exception('Fingerprint does not match the key file');
}

Type guard

function isValidFingerprintString(mixed $fp): bool
{
    return is_string($fp) && (bool)preg_match('/^[A-F0-9]{40}$/', strtoupper(preg_replace('/\s+/', '', $fp)));
}

Try / catch

try {
    $gpg = $this->setVerifyKeyWithServerKey($gpg);
} catch (InternalErrorException $e) {
    Log::error('Verify key setup failed: ' . $e->getMessage());
    throw new InternalErrorException('Server signature verification unavailable; check key config.');
}

Prevention

When it happens

Trigger: Calling setVerifyKeyWithServerKey when the keyring has no key for passbolt.gpg.serverKey.fingerprint and importServerKeyInKeyring fails (missing/unreadable key file, invalid ASCII armor), or the gnupg context cannot be initialized with that fingerprint (malformed fingerprint string in config).

Common situations: serverkey.asc path misconfigured or file deleted during a cleanup; fingerprint copy/pasted with extra whitespace or wrong length; Docker image rebuilt without re-importing the key; keyring owned by a different system user than the one PHP runs as.

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

Appendix: source

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

        // 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 verify key as the one from the server
        try {
            $gpg->setVerifyKeyFromFingerprint($fingerprint);
        } catch (Exception $exception) {
            try {
                $gpg->importServerKeyInKeyring();
                $gpg->setVerifyKeyFromFingerprint($fingerprint);
            } catch (Exception $exception) {
                $msg = __('The OpenPGP server key defined in the config cannot be used to verify signature.') . ' ';
                $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 setSignKeyWithServerKey(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)