{"record":{"id":"3d2fa9308828ac14","repo":"passbolt/passbolt_api","slug":"the-jwt-public-key-could-not-be-extracted-jwtkeypairservice","errorCode":null,"errorMessage":"The JWT public key could not be extracted.","messagePattern":"The JWT public key could not be extracted\\.","errorType":"http","errorClass":"InvalidJwtKeyPairException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltCe/JwtAuthentication/src/Service/AccessToken/JwtKeyPairService.php","lineNumber":82,"sourceCode":"            'digest_alg' => JwtTokenCreateService::JWT_ALG,\n            'private_key_bits' => $this->getKeyLength(),\n            'private_key_type' => OPENSSL_KEYTYPE_RSA,\n        ];\n        $secretKeyPath = $this->getSecretKeyPath();\n        $publicKeyPath = $this->getPublicKeyPath();\n\n        try {\n            $pk = openssl_pkey_new($config);\n            if ($pk === false) {\n                throw new Exception('The JWT private key could not be created.');\n            }\n            $export = openssl_pkey_export_to_file($pk, $secretKeyPath);\n            if ($export === false) {\n                throw new Exception('The JWT private key could not be written.');\n            }\n            $publicKey = openssl_pkey_get_details($pk)['key'] ?? false;\n            if ($publicKey === false) {\n                throw new Exception('The JWT public key could not be extracted.');\n            }\n            $export = file_put_contents($publicKeyPath, $publicKey);\n            if ($export === false) {\n                throw new Exception('The JWT public key could not be written.');\n            }\n\n            $permission = 0640;\n            $res = chmod($secretKeyPath, $permission);\n            if (!$res) {\n                throw new Exception(\"The permission of $secretKeyPath could not be set to $permission.\");\n            }\n            $res = chmod($publicKeyPath, $permission);\n            if (!$res) {\n                throw new Exception(\"The permission of $publicKeyPath could not be set to $permission.\");\n            }\n        } catch (Throwable $e) {\n            throw new InvalidJwtKeyPairException($e->getMessage());\n        }","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/JwtAuthentication/src/Service/AccessToken/JwtKeyPairService.php#L64-L100","documentation":"openssl_pkey_get_details($pk)['key'] is used to extract the PEM public key from the freshly generated private key; the code treats a missing 'key' entry as false and throws this error. Since $pk was just generated successfully, this almost always indicates an internal OpenSSL/library failure rather than user error.","triggerScenarios":"openssl_pkey_get_details($pk) returns false or an array without 'key' immediately after a successful openssl_pkey_new/export in createKeyPair().","commonSituations":"Corrupted or exotic OpenSSL builds; memory exhaustion during key handling; non-RSA key types where 'key' handling differs; very low PHP memory_limit in CLI.","solutions":["Increase PHP memory_limit for CLI and retry the JWT key pair command","Re-run generation — a transient OpenSSL failure may not reproduce","Confirm openssl extension version compatibility with PHP (php -i | grep -A2 openssl)","Check for non-zero OpenSSL error strings immediately after the call"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// precondition: openssl extension loaded and memory_limit adequate\nif (ini_get('memory_limit') !== '-1' && \\Cake\\Utility\\Text::parseBytes(ini_get('memory_limit')) < 134217728) { ini_set('memory_limit', '256M'); }","typeGuard":"$details = openssl_pkey_get_details($pk);\n$publicKey = is_array($details) ? ($details['key'] ?? false) : false;","tryCatchPattern":"try { $service->createKeyPair(); } catch (InvalidJwtKeyPairException $e) { // retry once; persist if openssl_error_string() repeats }","preventionTips":["Retry key generation once on transient OpenSSL failures","Keep PHP memory_limit >= 256M for CLI","Use supported PHP/OpenSSL version pairings"],"tags":["openssl","jwt","internal"],"backgroundTag":"internal-invariant-violation","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"}