lcobucci/jwt · error · Lcobucci\JWT\Signer\InvalidKeyProvided

It was not possible to parse your key, reason

Error message

It was not possible to parse your key, reason:{opensslError}

What it means

Thrown by OpenSSL::validateKey when openssl_pkey_get_private/get_public returns false, i.e. OpenSSL could not parse the provided key material at all. The message includes the OpenSSL error buffer with the parse failure reason.

Solutions

  1. Validate the key parses outside PHP: `openssl pkey -in key.pem -noout`
  2. If storing the key in an env var, use literal \n escapes and restore newlines before parsing, or load from a file
  3. Make sure you pass a key, not a certificate (extract key: `openssl pkey -in cert.pem -pubout` style, or use the certificate's key)
  4. Verify PEM headers are intact (-----BEGIN ... PRIVATE KEY----- / -----END ...)

Example fix

// before
$pem = str_replace('\n', '', getenv('PRIVATE_KEY')); // newlines lost
$key = InMemory::plainText($pem);
// after
$pem = str_replace('\\n', "\n", getenv('PRIVATE_KEY'));
$key = InMemory::plainText($pem);
Defensive patterns

Strategy: validation

Validate before calling

if (strpos($pem, '-----BEGIN') !== 0) { throw new InvalidArgumentException('Key must be PEM with BEGIN/END headers'); }

Try / catch

try { $signer->sign($payload, $key); } catch (\Jose\Component\Signature\Exception\InvalidKeyProvided $e) { /* log $e->getMessage() which contains OpenSSL parse reason */ }

Prevention

When it happens

Trigger: Passing malformed PEM/DER contents, a key missing the BEGIN/END headers (e.g. only base64 body), an X.509 certificate instead of a key, or whitespace-mangled key contents from env vars or JSON config.

Common situations: Keys pasted through env vars losing newlines, certificate (cert.pem) used where a key file is expected, base64 re-encoding stripping headers, older PHP without modern key import for certain formats (e.g. PKCS#8 on very old setups).

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of lcobucci/jwt@375813049c (2026-09-14). Data as JSON: /api/errors/3eefbf4100924cf4. Report an issue: GitHub.

Appendix: source

Thrown at src/Signer/OpenSSL.php:91

        return $result === 1;
    }

    /** @throws InvalidKeyProvided */
    private function getPublicKey(Key $key): OpenSSLAsymmetricKey
    {
        return $this->validateKey(openssl_pkey_get_public($key->contents()));
    }

    /**
     * Raises an exception when the key type is not the expected type
     *
     * @throws InvalidKeyProvided
     */
    private function validateKey(OpenSSLAsymmetricKey|bool $key): OpenSSLAsymmetricKey
    {
        if (is_bool($key)) {
            throw InvalidKeyProvided::cannotBeParsed($this->fullOpenSSLErrorString());
        }

        $details = openssl_pkey_get_details($key);
        assert(is_array($details));

        assert(array_key_exists('bits', $details));
        assert(is_int($details['bits']));
        assert(array_key_exists('type', $details));
        assert(is_int($details['type']));

        $this->guardAgainstIncompatibleKey($details['type'], $details['bits']);
        $this->guardAgainstIncompatibleCurve($this->curveNameFrom($details));

        return $key;
    }

    /** @param array<string, mixed> $details */
    private function curveNameFrom(array $details): ?string

View on GitHub (pinned to 375813049c)