{"record":{"id":"1f4971cf1b5f9d3d","repo":"passbolt/passbolt_api","slug":"the-config-for-the-server-private-key-fingerprint-is-not","errorCode":null,"errorMessage":"The config for the server private key fingerprint is not available or incomplete.","messagePattern":"The config for the server private key fingerprint is not available or incomplete\\.","errorType":"exception","errorClass":"Cake\\Http\\Exception\\InternalErrorException","httpStatus":500,"severity":"critical","filePath":"plugins/PassboltCe/JwtAuthentication/src/Authenticator/GpgJwtAuthenticator.php","lineNumber":362,"sourceCode":"            );\n        } catch (Exception $exception) {\n            Log::error($exception->getMessage() . \"\\n\" . $clearTextChallenge);\n            throw new BadRequestException(__('The challenge is invalid. Validation Failed.'));\n        }\n\n        return $verifyToken;\n    }\n\n    /**\n     * @param mixed $fingerprint fingerprint\n     * @throws \\Cake\\Http\\Exception\\InternalErrorException\n     * @return void\n     */\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","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/JwtAuthentication/src/Authenticator/GpgJwtAuthenticator.php#L344-L380","documentation":"assertServerFingerprint validates that the configured server private key fingerprint is a string passing PublicKeyValidationService::isValidFingerprint. It throws InternalErrorException (500) because a missing/invalid server fingerprint is a server configuration problem, not a client mistake.","triggerScenarios":"setServerKey runs during GPG JWT authentication bootstrap when passbolt.json / passbolt.php lacks passbolt.gpg.serverKey.fingerprint, or the value is not a valid 40-char hex fingerprint.","commonSituations":"Fresh install where `passbolt create_user`/key install steps were skipped; config import lost the serverKey block; fingerprint pasted with spaces or lowercase/short form; env var PASSBOLT_GPG_SERVER_KEY_FINGERPRINT not set in container.","solutions":["Set passbolt.gpg.serverKey.fingerprint in config/passbolt.php or passbolt.json to the full 40-character uppercase fingerprint","Run `gpg --list-keys --fingerprint | grep -i passbolt` as the web server user and copy the fingerprint exactly","Ensure the env variable (e.g. PASSBOLT_GPG_SERVER_KEY_FINGERPRINT) is defined in the deployment environment","Re-run the server key import step (`passbolt install` key import or gpg --import serverkey.asc)`","Run `ddev refresh` / `passbolt healthcheck` to confirm the server key config check passes"],"exampleFix":"// before config/passbolt.php\n'serverKey' => ['fingerprint' => null],\n// after\n'serverKey' => ['fingerprint' => getenv('PASSBOLT_GPG_SERVER_KEY_FINGERPRINT')], // e.g. '0FC3E17C88AE067DD66B2D5A0B9BD6D9FA2C1A2F'","handlingStrategy":"validation","validationCode":"const fp = config.passbolt.gpg.serverKey.fingerprint;\nif (typeof fp !== 'string' || !/^[A-F0-9]{40}$/.test(fp)) throw new Error('server key fingerprint config missing/invalid');","typeGuard":"function hasValidFingerprint(v) { return typeof v === 'string' && /^[0-9A-F]{40}$/.test(v); }","tryCatchPattern":"try { await login(); } catch (e) { if (e.status === 500 && /fingerprint is not available/.test(e.message)) { await runServerKeySetup(); } }","preventionTips":["Set serverKey.fingerprint during provisioning and verify with passbolt healthcheck","Use the full 40-char uppercase fingerprint","Pin the fingerprint via env var so container rebuilds keep it","Check config after every restore/migration"],"tags":["configuration","gpg","server-key","fingerprint"],"backgroundTag":"missing-required-config-field","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"}