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
- Compare `passbolt.gpg.serverKey.fingerprint` against `gpg --show-keys <serverKey.path>` — fix any mismatch or whitespace.
- Ensure passbolt.gpg.serverKey.path points to an existing, readable public key file and that `public` config is true if serving it.
- Import manually as the web server user: `sudo -H -u www-data gpg --home <gnupghome> --import /etc/passbolt/serverkey.asc`, then retry the request.
- Fix GNUPGHOME permissions (owned by web user, mode 700) so the import into the keyring can succeed.
- 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
- Normalize fingerprints (strip whitespace, uppercase) when injecting them from env/config.
- Verify the key file exists and fingerprint matches at deploy time with gpg --show-keys.
- Set passbolt.gpg.serverKey.public correctly if the key is served to clients.
- Mount the keyring persistently in containerized deployments.
- Run the OpenPGP healthcheck after every image rebuild.
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
- The message cannot be verified.
- Decryption failed. Invalid signature. Expected
- The OpenPGP server key defined in the config cannot be…
- The OpenPGP server key defined in the config cannot be used…
- The OpenPGP server key defined in the config cannot be used…
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 passphraseView on GitHub (pinned to 31c1bbc10f)