composer/composer · error · TransportException
The configured capath was not valid or could not be read.
Error message
The configured capath was not valid or could not be read.
What it means
Thrown by StreamContextFactory::getTlsDefaults() when a configured ssl.capath either is not a directory or is not readable. capath must be an OpenSSL-style hashed certificate directory.
Source
Thrown at src/Composer/Util/StreamContextFactory.php:233
* Attempt to find a local cafile or throw an exception if none pre-set
* The user may go download one if this occurs.
*/
if (!isset($defaults['ssl']['cafile']) && !isset($defaults['ssl']['capath'])) {
$result = CaBundle::getSystemCaRootBundlePath($logger);
if (is_dir($result)) {
$defaults['ssl']['capath'] = $result;
} else {
$defaults['ssl']['cafile'] = $result;
}
}
if (isset($defaults['ssl']['cafile']) && (!Filesystem::isReadable($defaults['ssl']['cafile']) || !CaBundle::validateCaFile($defaults['ssl']['cafile'], $logger))) {
throw new TransportException('The configured cafile was not valid or could not be read.');
}
if (isset($defaults['ssl']['capath']) && (!is_dir($defaults['ssl']['capath']) || !Filesystem::isReadable($defaults['ssl']['capath']))) {
throw new TransportException('The configured capath was not valid or could not be read.');
}
/**
* Disable TLS compression to prevent CRIME attacks where supported.
*/
$defaults['ssl']['disable_compression'] = true;
return $defaults;
}
/**
* A bug in PHP prevents the headers from correctly being sent when a content-type header is present and
* NOT at the end of the array
*
* This method fixes the array by moving the content-type header to the end
*
* @link https://bugs.php.net/bug.php?id=61548
* @param string|string[] $headerView on GitHub (pinned to 6ffc117740)
Solutions
- Point ssl.capath at an actual OpenSSL hashed certificate directory (c_rehash), or unset it and use ssl.cafile instead.
- Fix read permissions on the directory.
- If unsure, unset the manual capath and let Composer use the system bundle.
Example fix
// before composer config ssl.capath /etc/ssl/single-cert.pem // after: use a real hashed dir, or fall back to cafile composer config --unset ssl.capath
Defensive patterns
Strategy: validation
Validate before calling
$capath = $configuredCapath;
if ($capath && (!is_dir($capath) || !is_readable($capath))) {
throw new \RuntimeException('Invalid capath: '.$capath);
} Prevention
- Use ssl.cafile unless you specifically need a hashed cert directory.
- Run c_rehash after adding certs to a capath directory.
- Validate the path exists and is readable before configuring it.
When it happens
Trigger: ssl.capath is set in config/options and either is_dir() is false or Filesystem::isReadable() is false at StreamContextFactory.php:232.
Common situations: Pointing capath at a single .pem file instead of a hashed cert directory; wrong path; missing read permissions; the directory has no hashed symlinks so OpenSSL can't use it (though Composer only checks dir + readable here).
Related errors
- The configured cafile was not valid or could not be read.
- The '{fileUrl}' URL could not be accessed: {message}
- You must enable the openssl extension to use a secure proxy.
- You must enable the curl extension to make https requests th
- You must enable the openssl extension to make https requests
AI-assisted analysis of composer/composer@6ffc117740 (2026-08-07).
Data as JSON: /api/errors/8b5d63590ce6c87a.
Report an issue: GitHub.