passbolt/passbolt_api · error · InvalidJwtKeyPairException
The JWT private key could not be created.
Error message
The JWT private key could not be created.
What it means
JwtKeyPairService::createKeyPair() calls openssl_pkey_new($config) to generate the RSA JWT key pair. When OpenSSL fails to create the key resource (returns false), this error is thrown and later wrapped in InvalidJwtKeyPairException. It means the local OpenSSL library refused to generate a key with the supplied configuration.
Solutions
- Verify the openssl.cnf exists and OPENSSL_CONF points to it (php -i | grep openssl; check `openssl version -d`)
- Set a valid config in createKeyPair's $config, e.g. 'config' => a path to a working openssl.cnf with [req] distinguished_name and [rsa] sections
- Ensure the PHP openssl extension is loaded and functioning (php -m | grep openssl; openssl_pkey_new smoke test)
- Check the container image ships /etc/ssl/openssl.cnf; if not, add one
Example fix
// before $pk = openssl_pkey_new($config); // fails: no config // after $config = [ 'private_key_bits' => 4096, 'private_key_type' => OPENSSL_KEYTYPE_RSA, 'config' => '/etc/ssl/openssl.cnf', ]; $pk = openssl_pkey_new($config);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!extension_loaded('openssl')) { throw new \RuntimeException('openssl extension missing'); }
if (!is_file('/etc/ssl/openssl.cnf')) { /* warn: OpenSSL config missing */ } Type guard
$pk = openssl_pkey_new($config);
if (!is_resource($pk) && !($pk instanceof \OpenSSLAsymmetricKey)) { /* handle failure */ } Try / catch
try {
$service->createKeyPair();
} catch (\Passbolt\JwtAuthentication\Error\Exception\AccessToken\InvalidJwtKeyPairException $e) {
// inspect openssl_error_string() and OPENSSL_CONF before retrying
} Prevention
- Ship a valid openssl.cnf in container images
- Set OPENSSL_CONF explicitly in CLI and web SAPI environments
- Smoke-test openssl_pkey_new in deploy health checks
When it happens
Trigger: Running the JWT key pair generation command (execute -> createKeyPair) when openssl_pkey_new returns false, typically because the openssl.cnf path is wrong/missing or the config lacks an 'rsKeys'/'req' section (e.g. OPENSSL_CONF pointing at an empty file, default 'private_key_bits'/'private_key_type' unsupported).
Common situations: Docker/minimal images without a valid openssl.cnf; OPENSSL_CONF env var pointing to a nonexistent file; OpenSSL 3.x strictness with legacy config; passboltEmail or CLI user environment missing default openssl config.
Related errors
- The domain is invalid. Expected
- The JWT private key could not be written.
- The JWT public key could not be extracted.
- The JWT public key could not be extracted.
- The JWT public key details could not be read.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/ecc08a33ddb706d2.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/JwtAuthentication/src/Service/AccessToken/JwtKeyPairService.php:74
public function createKeyPair(bool $force = false): void
{
// If pair exists but force to false, exit silently
if ($this->keyPairExists() && !$force) {
return;
}
$config = [
'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.");View on GitHub (pinned to 31c1bbc10f)