{"record":{"id":"39be8b1fa79059c6","repo":"passbolt/passbolt_api","slug":"the-config-for-the-server-private-key-passphrase-is-invalid","errorCode":null,"errorMessage":"The config for the server private key passphrase is invalid.","messagePattern":"The config for the server private key passphrase is invalid\\.","errorType":"exception","errorClass":"Cake\\Http\\Exception\\InternalErrorException","httpStatus":500,"severity":"critical","filePath":"plugins/PassboltCe/JwtAuthentication/src/Authenticator/GpgJwtAuthenticator.php","lineNumber":375,"sourceCode":"     */\n    public function assertServerFingerprint(mixed $fingerprint): void\n    {\n        if (!is_string($fingerprint) || !PublicKeyValidationService::isValidFingerprint($fingerprint)) {\n            $msg = __('The config for the server private key fingerprint is not available or incomplete.');\n            throw new InternalErrorException($msg);\n        }\n    }\n\n    /**\n     * @param mixed $passphrase passphrase\n     * @throws \\Cake\\Http\\Exception\\InternalErrorException\n     * @return void\n     */\n    public function assertServerPassphrase(mixed $passphrase): void\n    {\n        if (!is_string($passphrase)) {\n            $msg = __('The config for the server private key passphrase is invalid.');\n            throw new InternalErrorException($msg);\n        }\n    }\n\n    /**\n     * @param mixed $userId uuid\n     * @throws \\Cake\\Http\\Exception\\BadRequestException\n     * @return void\n     */\n    public function assertUserId(mixed $userId): void\n    {\n        if (!is_string($userId) || !Validation::uuid($userId)) {\n            $msg = __('The user id is missing or invalid.');\n            throw new BadRequestException($msg);\n        }\n    }\n\n    /**\n     * @param mixed $userData data","sourceCodeStart":357,"sourceCodeEnd":393,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/JwtAuthentication/src/Authenticator/GpgJwtAuthenticator.php#L357-L393","documentation":"assertServerPassphrase checks the configured server key passphrase is a string (empty string allowed). A non-string value (null, int from config) raises InternalErrorException since passphrase typing is a server-side config defect.","triggerScenarios":"setServerKey bootstrap when passbolt.gpg.serverKey.passphrase is absent (null), set to a non-string type in passbolt.php, or an env-int interpolation yields a number instead of a string.","commonSituations":"Deployments where the passphrase env var is unset and config maps it directly (null); YAML/JSON config parsing '1234' as an integer; copy-pasted config omitting the passphrase key entirely.","solutions":["Define the passphrase as a string in config, e.g. 'passphrase' => (string)getenv('PASSBOLT_GPG_SERVER_KEY_PASSPHRASE')","If the key has no passphrase, set it explicitly to empty string '' rather than leaving it undefined","Quote the passphrase in passbolt.json/passbolt.php so numeric passphrases stay strings","Run passbolt healthcheck to verify server key configuration"],"exampleFix":"// before\n'passphrase' => getenv('PASSBOLT_GPG_SERVER_KEY_PASSPHRASE'), // null if unset\n// after\n'passphrase' => (string)(getenv('PASSBOLT_GPG_SERVER_KEY_PASSPHRASE') ?? ''),","handlingStrategy":"validation","validationCode":"const pp = config.passbolt.gpg.serverKey.passphrase;\nif (typeof pp !== 'string') throw new Error('server key passphrase must be a string (use \"\" if none)');","typeGuard":"function isStringPassphrase(v) { return typeof v === 'string'; }","tryCatchPattern":"try { await login(); } catch (e) { if (e.status === 500 && /passphrase is invalid/.test(e.message)) { fixPassphraseConfigType(); } }","preventionTips":["Always store the passphrase as a quoted string in config","Coerce env vars with (string) or String() before assigning","Use '' explicitly for passphrase-less keys","Validate config types in a boot-time check or healthcheck"],"tags":["configuration","gpg","passphrase","server-key"],"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"}