passbolt/passbolt_api · error · BadRequestException
Provided root CA file does not exist
Error message
Provided root CA file does not exist
What it means
This BadRequestException is thrown by SsoHttpClientFactory::resolveVerify when the `passbolt.security.sso.sslCafile` config points to a path that does not exist on the server filesystem. The library validates the CA bundle path before wiring it into the HTTP client used for SSO/OAuth2 TLS verification, failing fast to avoid silent certificate trust issues later.
Solutions
- Check the configured path with `ls -l` on the server (inside the container if applicable) and fix `passbolt.security.sso.sslCafile` in config/passbolt.php or environment config to point at an existing CA bundle.
- If no custom CA is needed, remove/unset the sslCafile config entry so resolveVerify returns early and uses system defaults.
- If the CA file lives outside the container, mount it into the container and reference the in-container path.
- Ensure the file is readable by the web-server/PHP user (existence also implies readable for file_exists, but verify permissions for fopen).
Example fix
// before 'passbolt' => ['security' => ['sso' => ['sslCafile' => '/etc/ssl/custom-ca.pem']]], // file absent // after 'passbolt' => ['security' => ['sso' => ['sslCafile' => '/etc/ssl/certs/ca-certificates.crt']]], // verified with ls
Defensive patterns
Strategy: validation
Validate before calling
$cafile = Configure::read('passbolt.security.sso.sslCafile');
if (is_string($cafile) && !file_exists($cafile)) {
throw new RuntimeException("sslCafile does not exist: $cafile");
} Type guard
function isValidCafilePath(mixed $path): bool {
return is_string($path) && $path !== '' && file_exists($path) && is_readable($path);
} Try / catch
try {
$client = SsoHttpClientFactory::create();
} catch (BadRequestException $e) {
// check passbolt.security.sso.sslCafile points to an existing file
} Prevention
- Provision the CA file with deployment tooling and assert its existence in a pre-deploy health check
- Use OS-conditional config for default CA bundle paths (Debian vs RHEL)
- Mount CA files explicitly into containers and reference in-container paths
When it happens
Trigger: Calling SsoHttpClientFactory::create() while `passbolt.security.sso.sslCafile` is set to a string path that passes the is_string check but fails file_exists() — e.g. a typo'd path, a deleted file, or a path valid on another machine/container.
Common situations: Admins copy config from docs where the CA path differs per OS (/etc/ssl/certs/ca-certificates.crt vs /etc/pki/tls/certs/ca-bundle.crt); Docker volumes not mounting the CA file; the file was removed during a base image change or cert package update.
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.
Related errors
- Invalid `passbolt.plugins.smtpSettings.security`…
- Invalid value provided in `passbolt.security.sso.sslCafile`…
- No default expiry or expiry for token type
- The configuration value should be a string or NULL.
- The configuration value should be one of the following: .
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/1e67d11d9be1e8b1.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Utility/Http/SsoHttpClientFactory.php:73
* @return string|bool `true` for default verification, `false` to disable, or a CA file path.
* @throws \Cake\Http\Exception\BadRequestException When a custom CA file is configured but invalid.
*/
private static function resolveVerify(): bool|string
{
$sslVerify = (bool)Configure::read(self::CONFIG_SSL_VERIFY, true);
$sslCafile = Configure::read(self::CONFIG_SSL_CAFILE);
if ($sslVerify && $sslCafile === null) {
return true;
}
if (!$sslVerify) {
return false;
}
if (!is_string($sslCafile)) {
throw new BadRequestException(__('Invalid value provided in `passbolt.security.sso.sslCafile` config'));
}
if (!file_exists($sslCafile)) {
throw new BadRequestException(__('Provided root CA file does not exist'));
}
return $sslCafile;
}
}
View on GitHub (pinned to 31c1bbc10f)