{"record":{"id":"ddad5c4ad92d1bb8","repo":"passbolt/passbolt_api","slug":"the-openpgp-server-key-defined-in-the-config-cannot-be-used-ddad5c","errorCode":null,"errorMessage":"The OpenPGP server key defined in the config cannot be used to encrypt. ","messagePattern":"The OpenPGP server key defined in the config cannot be used to encrypt\\. ","errorType":"http","errorClass":"InternalErrorException","httpStatus":500,"severity":"critical","filePath":"src/Service/OpenPGP/OpenPGPCommonServerOperationsTrait.php","lineNumber":51,"sourceCode":"        // Check if config contains fingerprint\n        $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');\n        $this->assertServerFingerprint($fingerprint);\n\n        // Check if config contains valid passphrase\n        $passphrase = Configure::read('passbolt.gpg.serverKey.passphrase');\n        $this->assertServerPassphrase($passphrase);\n\n        // set the key to be used for encrypting\n        try {\n            $gpg->setEncryptKeyFromFingerprint($fingerprint);\n        } catch (Exception $exception) {\n            try {\n                $gpg->importServerKeyInKeyring();\n                $gpg->setEncryptKeyFromFingerprint($fingerprint);\n            } catch (Exception $exception) {\n                $msg = __('The OpenPGP server key defined in the config cannot be used to encrypt.') . ' ';\n                $msg .= $exception->getMessage();\n                throw new InternalErrorException($msg, 500, $exception);\n            }\n        }\n\n        return $gpg;\n    }\n\n    /**\n     * @param \\App\\Utility\\OpenPGP\\OpenPGPBackend $gpg for example OpenPGPBackendFactory::get()\n     * @return \\App\\Utility\\OpenPGP\\OpenPGPBackend backend configured to use server key to sign\n     * @throws \\Cake\\Http\\Exception\\InternalErrorException if the server key cannot be loaded\n     */\n    public function setDecryptKeyWithServerKey(OpenPGPBackend $gpg): OpenPGPBackend\n    {\n        // Check if config contains fingerprint\n        $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');\n        $this->assertServerFingerprint($fingerprint);\n\n        // Check if config contains valid passphrase","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Service/OpenPGP/OpenPGPCommonServerOperationsTrait.php#L33-L69","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","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.","Check GNUPGHOME permissions: the keyring directory and its files must be owned and writable by the web server user (chmod 700 on the dir).","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.","Read the appended $exception->getMessage() in the 500 response/logs — it names the exact gnupg failure (e.g. 'get key failed', 'import failed')."],"exampleFix":"// before (config/app.php)\n'fingerprint' => '0FC9E3A4FA0C08A79B8E1F4B57D5F0B200A8ABF7', // stale fingerprint\n// after\n'fingerprint' => '<fingerprint printed by: gpg --show-keys /etc/passbolt/serverkey.asc>',","handlingStrategy":"try-catch","validationCode":"// Run before requests / in a healthcheck\n$fp = Configure::read('passbolt.gpg.serverKey.fingerprint');\n$home = Configure::read('passbolt.gpg.serverKey.fingerprint');\nexec(sprintf('sudo -H -u www-data gpg --list-keys %s 2>/dev/null', escapeshellarg($fp)), $out, $code);\nif (!PublicKeyValidationService::isValidFingerprint($fp) || $code !== 0) {\n    throw new Exception('Server key missing from keyring or fingerprint invalid');\n}","typeGuard":"function isValidServerKeyFingerprint(mixed $fp): bool\n{\n    return is_string($fp) && PublicKeyValidationService::isValidFingerprint($fp);\n}","tryCatchPattern":"try {\n    $gpg = $this->setEncryptKeyWithServerKey($gpg);\n} catch (InternalErrorException $e) {\n    Log::error('Server key encrypt setup failed: ' . $e->getMessage());\n    throw new InternalErrorException('Server OpenPGP key is not operational; run the key import healthcheck.');\n}","preventionTips":["Import the server key into the web server user's keyring during deployment and verify with gpg --list-keys as that user.","Keep fingerprint, passphrase, and key file path in sync — regenerate all three together whenever the key changes.","Run the passbolt healthcheck in CI/after deploys to catch keyring drift early.","Pin GNUPGHOME to a persistent, correctly owned directory in containers.","Never run CLI maintenance as root against the web user's keyring without GNUPGHOME set."],"tags":["openpgp","gnupg","server-key","encryption","config"],"backgroundTag":"invalid-config-value","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}