lcobucci/jwt · error · Lcobucci\JWT\Signer\CannotSignPayload
There was an error while creating the signature
Error message
There was an error while creating the signature:{opensslError} What it means
Thrown by OpenSSL::createSignature when openssl_sign() returns false, meaning PHP's OpenSSL extension could not produce a signature. The message includes the accumulated OpenSSL error string, which usually explains why (key problems, algorithm mismatch, malformed key).
Solutions
- Run `openssl pkey -in key.pem -check` to confirm the private key is valid
- Make sure you pass the private key (not the public key) for signing
- Supply the passphrase if the key is encrypted (InMemory file contents / explicit passphrase)
- Check OpenSSL error details in the message and container OpenSSL version compatibility
Example fix
// before
$key = InMemory::file('/path/public.pem'); // public key cannot sign
// after
$key = InMemory::file('/path/private.pem'); Defensive patterns
Strategy: try-catch
Validate before calling
$res = openssl_pkey_get_private(file_get_contents($pem), $passphrase); if ($res === false) { throw new RuntimeException('Invalid private key: ' . openssl_error_string()); } Try / catch
try { $token = $builder->signedWith($key)->getToken(...); } catch (\Jose\Component\Signature\Exception\CannotSignPayload $e) { /* inspect OpenSSL error in message */ } Prevention
- Pre-check keys with `openssl pkey -check` in deployment scripts
- Distinguish private vs public key files by naming convention
- Record OpenSSL version in your environment; watch for LibreSSL quirks
When it happens
Trigger: Calling sign() with a private key that OpenSSL cannot load or use: invalid PEM contents, encrypted key without passphrase, wrong key type for the configured algorithm, or an uninitialized OpenSSLAsymmetricKey.
Common situations: Key file contains a public key where a private key is required, corrupted or truncated PEM, passphrase-protected key passed without the passphrase, LibreSSL/OpenSSL version differences on stripped containers (e.g. alpine).
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- It was not possible to parse your key, reason
- The type of the provided key is not
- The type of the provided key is not
- The curve of the provided key is not
- Invalid signature length.
AI-assisted analysis of lcobucci/jwt@375813049c (2026-09-14).
Data as JSON: /api/errors/0e4899bec16229ce.
Report an issue: GitHub.
Appendix: source
Thrown at src/Signer/OpenSSL.php:52
OPENSSL_KEYTYPE_EC => 'EC',
];
/**
* @return non-empty-string
*
* @throws CannotSignPayload
* @throws InvalidKeyProvided
*/
final protected function createSignature(
Key $key,
string $payload,
): string {
$opensslKey = $this->getPrivateKey($key);
$signature = '';
if (! openssl_sign($payload, $signature, $opensslKey, $this->algorithm())) {
throw CannotSignPayload::errorHappened($this->fullOpenSSLErrorString());
}
return $signature;
}
/** @throws CannotSignPayload */
private function getPrivateKey(
Key $key,
): OpenSSLAsymmetricKey {
return $this->validateKey(openssl_pkey_get_private($key->contents(), $key->passphrase()));
}
/** @throws InvalidKeyProvided */
final protected function verifySignature(
string $expected,
string $payload,
Key $key,
): bool {View on GitHub (pinned to 375813049c)