{"record":{"id":"6864cfbb00c6a215","repo":"passbolt/passbolt_api","slug":"the-openpgp-server-key-defined-in-the-config-cannot-be-used","errorCode":null,"errorMessage":"The OpenPGP server key defined in the config cannot be used to decrypt. ","messagePattern":"The OpenPGP server key defined in the config cannot be used to decrypt\\. ","errorType":"exception","errorClass":"Cake\\Http\\Exception\\InternalErrorException","httpStatus":500,"severity":"critical","filePath":"plugins/PassboltCe/JwtAuthentication/src/Authenticator/GpgJwtAuthenticator.php","lineNumber":220,"sourceCode":"        $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 decrypting\n        try {\n            $this->gpg->setSignKeyFromFingerprint($fingerprint, $passphrase);\n            $this->gpg->setDecryptKeyFromFingerprint($fingerprint, $passphrase);\n        } catch (Exception $exception) {\n            try {\n                $this->gpg->importServerKeyInKeyring();\n                $this->gpg->setSignKeyFromFingerprint($fingerprint, $passphrase);\n                $this->gpg->setDecryptKeyFromFingerprint($fingerprint, $passphrase);\n            } catch (Exception $exception) {\n                $msg = __('The OpenPGP server key defined in the config cannot be used to decrypt.') . ' ';\n                $msg .= $exception->getMessage();\n                throw new InternalErrorException($msg, 500, $exception);\n            }\n        }\n    }\n\n    /**\n     * Set user key\n     *\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if the user data is not valid\n     * @throws \\Cake\\Http\\Exception\\InternalErrorException if the user key cannot be loaded\n     * @return void\n     */\n    public function setUserKey(): void\n    {\n        try {\n            $this->gpg->setVerifyKeyFromFingerprint($this->user->gpgkey->fingerprint);\n            $this->gpg->setEncryptKeyFromFingerprint($this->user->gpgkey->fingerprint);\n        } catch (Exception $exception) {\n            // Try to import the key in keyring again","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/JwtAuthentication/src/Authenticator/GpgJwtAuthenticator.php#L202-L238","documentation":"setServerKey imports the configured OpenPGP server key into the GnuPG keyring and registers it as decrypt/sign key during authenticator init. If any of those gnupg operations throws, the message is prefixed with 'The OpenPGP server key defined in the config cannot be used to decrypt.' plus the underlying exception message, and rethrown as InternalErrorException. The JWT flow cannot proceed without a usable server key.","triggerScenarios":"JWT authentication bootstrap when: the server key fingerprint/passphrase in config is wrong; the key files (serverkey.asc / serverkey_private.asc) are missing or unreadable; the key cannot be imported into the keyring; the passphrase is incorrect; GnuPG is missing or the GNUPGHOME is not writable.","commonSituations":"Fresh deployments where `passbolt create_user`/serverkey generation step was skipped; wrong 'passbolt.gpg.keyring' or JWT server key config after migrating servers; keyring permission issues under the web-server user (www-data); passphrase changed in config but not on the key.","solutions":["Read the appended underlying exception message in the response/log — it names the exact gnupg failure.","Verify the server key fingerprint and passphrase in config match the actual key files, and that both public and private key files exist and are readable.","Regenerate or re-import the server key into the keyring (e.g. passbolt serverkey commands / gpg --import as the web user).","Check the GNUPGHOME directory (~/.gnupg of the web-server user) exists, is writable, and gpg binary is installed.","Ensure the passphrase in config is correct for the private key."],"exampleFix":"// before (config): wrong fingerprint/passphrase\n'fingerprint' => 'ABCD1234...',\n'passphrase' => '',\n\n// after: matching values for the imported key\n'fingerprint' => strtoupper(str_replace(' ', '', $realFingerprint)),\n'passphrase' => $actualKeyPassphrase","handlingStrategy":"validation","validationCode":"// healthcheck before auth flows\nconst ok = await fetch('/healthcheck/status.json').then(r => r.json());\nif (!ok.body.gpg) throw new Error('Server GPG key not functional — fix config/keyring first');","typeGuard":null,"tryCatchPattern":"try { await jwtLogin(); } catch (e) { if (e.message.includes('cannot be used to decrypt')) reportServerConfigIssue(e.message); else throw e; }","preventionTips":["Run the passbolt healthcheck after every deployment to validate the server key.","Keep server key files and config fingerprint/passphrase in sync (config as code).","Verify GNUPGHOME ownership/permissions for the web-server user after OS upgrades.","Test key import with gpg CLI as the web user before switching environments."],"tags":["gpg","jwt","server-key","config","gnupg"],"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"}