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
- Validate the key parses outside PHP: `openssl pkey -in key.pem -noout`
- If storing the key in an env var, use literal \n escapes and restore newlines before parsing, or load from a file
- Make sure you pass a key, not a certificate (extract key: `openssl pkey -in cert.pem -pubout` style, or use the certificate's key)
- 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
- Load keys from files, not env vars, when possible to preserve newlines
- Never strip or re-wrap PEM line breaks
- Confirm you have a key, not a certificate, before signing
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
- There was an error while creating the signature
- The type of the provided key is not
- The curve of the provided key is not
- Invalid data. Should contain an integer.
- The path " " does not contain a valid key file
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): ?stringView on GitHub (pinned to 375813049c)