passbolt/passbolt_api · error · InvalidJwtKeyPairException

The JWT public key could not be extracted.

Error message

The JWT public key could not be extracted.

What it means

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.

Solutions

  1. Increase PHP memory_limit for CLI and retry the JWT key pair command
  2. Re-run generation — a transient OpenSSL failure may not reproduce
  3. Confirm openssl extension version compatibility with PHP (php -i | grep -A2 openssl)
  4. Check for non-zero OpenSSL error strings immediately after the call
Defensive patterns

Strategy: retry

Validate before calling

// precondition: openssl extension loaded and memory_limit adequate
if (ini_get('memory_limit') !== '-1' && \Cake\Utility\Text::parseBytes(ini_get('memory_limit')) < 134217728) { ini_set('memory_limit', '256M'); }

Type guard

$details = openssl_pkey_get_details($pk);
$publicKey = is_array($details) ? ($details['key'] ?? false) : false;

Try / catch

try { $service->createKeyPair(); } catch (InvalidJwtKeyPairException $e) { // retry once; persist if openssl_error_string() repeats }

Prevention

When it happens

Trigger: openssl_pkey_get_details($pk) returns false or an array without 'key' immediately after a successful openssl_pkey_new/export in createKeyPair().

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/3d2fa9308828ac14. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/JwtAuthentication/src/Service/AccessToken/JwtKeyPairService.php:82

            'digest_alg' => JwtTokenCreateService::JWT_ALG,
            'private_key_bits' => $this->getKeyLength(),
            'private_key_type' => OPENSSL_KEYTYPE_RSA,
        ];
        $secretKeyPath = $this->getSecretKeyPath();
        $publicKeyPath = $this->getPublicKeyPath();

        try {
            $pk = openssl_pkey_new($config);
            if ($pk === false) {
                throw new Exception('The JWT private key could not be created.');
            }
            $export = openssl_pkey_export_to_file($pk, $secretKeyPath);
            if ($export === false) {
                throw new Exception('The JWT private key could not be written.');
            }
            $publicKey = openssl_pkey_get_details($pk)['key'] ?? false;
            if ($publicKey === false) {
                throw new Exception('The JWT public key could not be extracted.');
            }
            $export = file_put_contents($publicKeyPath, $publicKey);
            if ($export === false) {
                throw new Exception('The JWT public key could not be written.');
            }

            $permission = 0640;
            $res = chmod($secretKeyPath, $permission);
            if (!$res) {
                throw new Exception("The permission of $secretKeyPath could not be set to $permission.");
            }
            $res = chmod($publicKeyPath, $permission);
            if (!$res) {
                throw new Exception("The permission of $publicKeyPath could not be set to $permission.");
            }
        } catch (Throwable $e) {
            throw new InvalidJwtKeyPairException($e->getMessage());
        }

View on GitHub (pinned to 31c1bbc10f)