{"record":{"id":"125729396fb0d02e","repo":"passbolt/passbolt_api","slug":"the-key-pair-for-jwt-authentication-is-not-complete","errorCode":null,"errorMessage":"The key pair for JWT Authentication is not complete.","messagePattern":"The key pair for JWT Authentication is not complete\\.","errorType":"http","errorClass":"InvalidJwtKeyPairException","httpStatus":500,"severity":"critical","filePath":"plugins/PassboltCe/JwtAuthentication/src/Service/AccessToken/JwtAbstractService.php","lineNumber":55,"sourceCode":"    }\n\n    /**\n     * @return string Path to the secret/private key file\n     */\n    public function getKeyPath(): string\n    {\n        return $this->keyPath;\n    }\n\n    /**\n     * @return string|false Content of the secret/private key file\n     * @throws \\Passbolt\\JwtAuthentication\\Error\\Exception\\AccessToken\\InvalidJwtKeyPairException if the file is not found or not readable.\n     */\n    public function readKeyFileContent(): string|false\n    {\n        if (!is_readable($this->getKeyPath())) {\n            $userErrorMessage = __('The key pair for JWT Authentication is not complete.');\n            throw new InvalidJwtKeyPairException($userErrorMessage);\n        }\n\n        return file_get_contents($this->getKeyPath());\n    }\n}\n","sourceCodeStart":37,"sourceCodeEnd":61,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/JwtAuthentication/src/Service/AccessToken/JwtAbstractService.php#L37-L61","documentation":"Thrown by JwtAbstractService::readKeyFileContent when the configured JWT key file path is not readable (is_readable() returns false). Raised as InvalidJwtKeyPairException, indicating the JWT authentication key pair is missing or inaccessible.","triggerScenarios":"Any JWT operation (token creation, JWKS retrieval, raw public key read) when config/jwt/jwt.public.key or jwt.private.key does not exist or the web-server user cannot read it.","commonSituations":"Fresh install where create_jwt_keys was never run; keys not synced across a multi-server deployment; wrong ownership/permissions after deployment; key directory deleted or mounted empty in containers.","solutions":["Generate the key pair: bin/cake passbolt create_jwt_keys","Fix permissions: chown www-data:www-data config/jwt/*.pem && chmod 640 config/jwt/*.pem (and 750 on the directory)","Ensure config/jwt exists and the path in configuration points to the real key location","In containerized setups, verify the secret volume is mounted and readable by the PHP user"],"exampleFix":"// before\n// config/jwt/ missing or unreadable\n// after\nbin/cake passbolt create_jwt_keys\nchown -R www-data:www-data config/jwt && chmod 750 config/jwt && chmod 640 config/jwt/*.pem","handlingStrategy":"validation","validationCode":"$path = config('passbolt.jwt.keyPath');\nif (!is_file($path) || !is_readable($path)) failFast('JWT key missing/unreadable: ' . $path);","typeGuard":null,"tryCatchPattern":"try { $token = $jwtService->createToken(); } catch (InvalidJwtKeyPairException $e) { runCreateJwtKeys(); }","preventionTips":["Run bin/cake passbolt create_jwt_keys on every new install","Include key existence in healthchecks and container readiness probes","Set stable ownership/permissions in deployment automation","Mount the same key pair on all app servers"],"tags":["jwt","file-not-found","permissions","configuration"],"backgroundTag":"file-not-found","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}