passbolt/passbolt_api · critical · InvalidJwtKeyPairException
The JWT public key could not be extracted.
Error message
The JWT public key could not be extracted.
What it means
Thrown by JwksGetService::getDetails when openssl_pkey_get_public() fails to parse the JWT public key file contents into a usable OpenSSL key resource. This signals the PEM file at the configured jwt key path is corrupt, empty, or not a valid public key.
Solutions
- Regenerate the JWT key pair: bin/cake passbolt create_jwt_keys
- Verify the PEM content: openssl pkey -pubin -in config/jwt/jwt.public.key -text -noout
- Check file permissions/readability for the web server user and that the file isn't empty
- If keys come from env/secret mount, confirm the secret contents are the full PEM, not base64 or truncated
Example fix
// regenerate bin/cake passbolt create_jwt_keys // verify openssl pkey -pubin -in config/jwt/jwt.public.key -noout
Defensive patterns
Strategy: validation
Validate before calling
$pub = file_get_contents($path);
if (empty($pub) || openssl_pkey_get_public($pub) === false) {
throw new RuntimeException('jwt.public.key invalid at ' . $path);
} Try / catch
try { $jwks = $service->getPublicKey(); } catch (InvalidJwtKeyPairException $e) { regenerateKeys(); } Prevention
- Run create_jwt_keys during provisioning, idempotently
- Validate PEMs with openssl at deploy time
- Mount secrets as raw PEM, never base64-wrapped or truncated
When it happens
Trigger: Building the JWKS (getPublicKey/getSecretKeySize) when the jwt.public.key file contains garbage, an HTML error page, an encrypted key, or truncated content.
Common situations: Key pair generation failed or was interrupted; file overwritten during deployment; wrong file mounted (e.g. private key expected but public slot holds something else); copy/paste artifacts in the PEM.
Related errors
- The JWT public key details could not be read.
- The configuration is not correctly set.
- The domain is invalid.
- The JWT private key could not be created.
- The JWT private key could not be written.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/384eb9a1af622329.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/JwtAuthentication/src/Service/AccessToken/JwksGetService.php:64
* @return int
*/
public function getSecretKeySize(): int
{
$details = $this->getDetails();
return $details['bits'] ?? 0;
}
/**
* @return array
* @throws \Passbolt\JwtAuthentication\Error\Exception\AccessToken\InvalidJwtKeyPairException if the public key file is not parsable.
*/
private function getDetails(): array
{
$pubKey = $this->readKeyFileContent();
$res = openssl_pkey_get_public($pubKey);
if ($res === false) {
throw new InvalidJwtKeyPairException(__('The JWT public key could not be extracted.'));
}
$details = openssl_pkey_get_details($res);
if ($details === false) {
throw new InvalidJwtKeyPairException(__('The JWT public key details could not be read.'));
}
return $details;
}
/**
* @return string|false
* @throws \Passbolt\JwtAuthentication\Error\Exception\AccessToken\InvalidJwtKeyPairException if the public key file is not found or not readable.
*/
public function getRawPublicKey(): string|false
{
return $this->readKeyFileContent();
}
}View on GitHub (pinned to 31c1bbc10f)