passbolt/passbolt_api · critical · InternalErrorException
The GnuPG config for the server is not available or…
Error message
The GnuPG config for the server is not available or incomplete.
What it means
Thrown by GpgAuthenticator::_initKeyring() when the configured server OpenPGP key fingerprint (passbolt.gpg.serverKey.fingerprint) is missing or not a syntactically valid fingerprint. The GPGAuth protocol requires the server key to decrypt user tokens, so authentication cannot proceed without it. It is a server-side configuration failure, reported as InternalErrorException (HTTP 500).
Solutions
- Set a valid 40-hex-character fingerprint under 'passbolt.gpg.serverKey.fingerprint' in config/app.local.php (or via the passbolt config generation).
- Regenerate/import a server key if none exists: run the passbolt serverkey generation/import command, then `passbolt healthcheck` to confirm the GPG section passes.
- Verify the app is loading the expected config file (check APP_BASE/config paths, container volume mounts) and that no override sets the fingerprint to null/empty.
- Run `passbolt cleanup`/healthcheck and restart PHP/web container so cached config is reloaded after fixing.
Example fix
// before (config/app.local.php)
'gpg' => ['serverKey' => ['fingerprint' => null]],
// after
'gpg' => ['serverKey' => [
'fingerprint' => '2FC8945813C523E1C25EDF0C6F91C027E4645C9B',
'public' => CONFIG . 'gpg' . DS . 'serverkey.asc',
'private' => CONFIG . 'gpg' . DS . 'serverkey_private.asc',
]], Defensive patterns
Strategy: validation
Validate before calling
$fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');
if (!is_string($fingerprint) || !PublicKeyValidationService::isValidFingerprint($fingerprint)) {
// fail fast / abort boot before handling GPGAuth requests
} Type guard
function isValidServerFingerprint(mixed $fingerprint): bool {
return is_string($fingerprint) && PublicKeyValidationService::isValidFingerprint($fingerprint);
} Try / catch
try {
$auth->authenticate($request);
} catch (InternalErrorException $e) {
// log config error, return 500 with guidance to run passbolt healthcheck
} Prevention
- Run `passbolt healthcheck` as part of deployment; it validates the GPG config section.
- Generate app.local.php via the official install flow instead of hand-editing fingerprints.
- Pin the server key fingerprint in an env var and validate it at boot.
- Add a smoke test that performs a GPGAuth stage0 request after each deploy.
When it happens
Trigger: Any GPGAuth request (login stage0+) triggers _initForAllSteps -> _initKeyring; the error is thrown when Configure::read('passbolt.gpg.serverKey.fingerprint') returns null/non-string, an empty string, or a string failing PublicKeyValidationService::isValidFingerprint() (wrong length/characters).
Common situations: Fresh installs where app.php/app.local.php was never populated with the server key fingerprint; running `passbolt install` or key generation was skipped; the fingerprint was hand-edited with a typo or lowercase-with-spaces variant the validator rejects; config file loaded from the wrong path in a container; environment variable interpolation produced an empty value.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- The OpenPGP server key defined in the config cannot be used…
- Could not import the user OpenPGP key.
- No default expiry or expiry for token type
- The config for the server private key fingerprint is not…
- The config for the server private key passphrase is invalid.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/10793a0e4a6032bb.
Report an issue: GitHub.
Appendix: source
Thrown at src/Authenticator/GpgAuthenticator.php:336
return true;
}
/**
* Initialize OpenPGP keyring and load the config
*
* @throws \Cake\Http\Exception\InternalErrorException if config is missing or key is not set nor usable to decrypt
* @return void
*/
private function _initKeyring(): void
{
// check if the default key is set and available in gpg
$this->_gpg = OpenPGPBackendFactory::get();
$fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');
$passphrase = Configure::read('passbolt.gpg.serverKey.passphrase');
// Check if config contains fingerprint
if (!is_string($fingerprint) || !PublicKeyValidationService::isValidFingerprint($fingerprint)) {
throw new InternalErrorException('The GnuPG config for the server is not available or incomplete.');
}
// set the key to be used for decrypting
try {
$this->_gpg->setDecryptKeyFromFingerprint($fingerprint, $passphrase);
} catch (Exception $exception) {
try {
$this->_gpg->importServerKeyInKeyring();
$this->_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);
}
}
}
/**View on GitHub (pinned to 31c1bbc10f)