passbolt/passbolt_api · critical · InvalidJwtKeyPairException
The key pair for JWT Authentication is not complete.
Error message
The key pair for JWT Authentication is not complete.
What it means
Thrown by JwtAbstractService::readKeyFileContent when the configured JWT key file path is not readable (is_readable() returns false). Raised as InvalidJwtKeyPairException, indicating the JWT authentication key pair is missing or inaccessible.
Solutions
- Generate the key pair: bin/cake passbolt create_jwt_keys
- Fix permissions: chown www-data:www-data config/jwt/*.pem && chmod 640 config/jwt/*.pem (and 750 on the directory)
- Ensure config/jwt exists and the path in configuration points to the real key location
- In containerized setups, verify the secret volume is mounted and readable by the PHP user
Example fix
// before // config/jwt/ missing or unreadable // after bin/cake passbolt create_jwt_keys chown -R www-data:www-data config/jwt && chmod 750 config/jwt && chmod 640 config/jwt/*.pem
Defensive patterns
Strategy: validation
Validate before calling
$path = config('passbolt.jwt.keyPath');
if (!is_file($path) || !is_readable($path)) failFast('JWT key missing/unreadable: ' . $path); Try / catch
try { $token = $jwtService->createToken(); } catch (InvalidJwtKeyPairException $e) { runCreateJwtKeys(); } Prevention
- Run bin/cake passbolt create_jwt_keys on every new install
- Include key existence in healthchecks and container readiness probes
- Set stable ownership/permissions in deployment automation
- Mount the same key pair on all app servers
When it happens
Trigger: Any JWT operation (token creation, JWKS retrieval, raw public key read) when config/jwt/jwt.public.key or jwt.private.key does not exist or the web-server user cannot read it.
Common situations: Fresh install where create_jwt_keys was never run; keys not synced across a multi-server deployment; wrong ownership/permissions after deployment; key directory deleted or mounted empty in containers.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The configuration is not correctly set.
- The domain is invalid.
- The JWT private key could not be written.
- The JWT public key could not be extracted.
- The JWT public key could not be read or is not valid.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/125729396fb0d02e.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/JwtAuthentication/src/Service/AccessToken/JwtAbstractService.php:55
}
/**
* @return string Path to the secret/private key file
*/
public function getKeyPath(): string
{
return $this->keyPath;
}
/**
* @return string|false Content of the secret/private key file
* @throws \Passbolt\JwtAuthentication\Error\Exception\AccessToken\InvalidJwtKeyPairException if the file is not found or not readable.
*/
public function readKeyFileContent(): string|false
{
if (!is_readable($this->getKeyPath())) {
$userErrorMessage = __('The key pair for JWT Authentication is not complete.');
throw new InvalidJwtKeyPairException($userErrorMessage);
}
return file_get_contents($this->getKeyPath());
}
}
View on GitHub (pinned to 31c1bbc10f)