{"record":{"id":"8b5d63590ce6c87a","repo":"composer/composer","slug":"the-configured-capath-was-not-valid-or-could-not-b","errorCode":null,"errorMessage":"The configured capath was not valid or could not be read.","messagePattern":"The configured capath was not valid or could not be read\\.","errorType":"exception","errorClass":"TransportException","httpStatus":null,"severity":"error","filePath":"src/Composer/Util/StreamContextFactory.php","lineNumber":233,"sourceCode":"         * Attempt to find a local cafile or throw an exception if none pre-set\n         * The user may go download one if this occurs.\n         */\n        if (!isset($defaults['ssl']['cafile']) && !isset($defaults['ssl']['capath'])) {\n            $result = CaBundle::getSystemCaRootBundlePath($logger);\n\n            if (is_dir($result)) {\n                $defaults['ssl']['capath'] = $result;\n            } else {\n                $defaults['ssl']['cafile'] = $result;\n            }\n        }\n\n        if (isset($defaults['ssl']['cafile']) && (!Filesystem::isReadable($defaults['ssl']['cafile']) || !CaBundle::validateCaFile($defaults['ssl']['cafile'], $logger))) {\n            throw new TransportException('The configured cafile was not valid or could not be read.');\n        }\n\n        if (isset($defaults['ssl']['capath']) && (!is_dir($defaults['ssl']['capath']) || !Filesystem::isReadable($defaults['ssl']['capath']))) {\n            throw new TransportException('The configured capath was not valid or could not be read.');\n        }\n\n        /**\n         * Disable TLS compression to prevent CRIME attacks where supported.\n         */\n        $defaults['ssl']['disable_compression'] = true;\n\n        return $defaults;\n    }\n\n    /**\n     * A bug in PHP prevents the headers from correctly being sent when a content-type header is present and\n     * NOT at the end of the array\n     *\n     * This method fixes the array by moving the content-type header to the end\n     *\n     * @link https://bugs.php.net/bug.php?id=61548\n     * @param  string|string[] $header","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/composer/composer/blob/6ffc1177404d0c50119c22dde6564a380f4a82c9/src/Composer/Util/StreamContextFactory.php#L215-L251","documentation":"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.","triggerScenarios":"ssl.capath is set in config/options and either is_dir() is false or Filesystem::isReadable() is false at StreamContextFactory.php:232.","commonSituations":"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).","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."],"exampleFix":"// before\ncomposer config ssl.capath /etc/ssl/single-cert.pem\n// after: use a real hashed dir, or fall back to cafile\ncomposer config --unset ssl.capath","handlingStrategy":"validation","validationCode":"$capath = $configuredCapath;\nif ($capath && (!is_dir($capath) || !is_readable($capath))) {\n    throw new \\RuntimeException('Invalid capath: '.$capath);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["tls","ca-bundle","config","php"],"analyzedSha":"6ffc1177404d0c50119c22dde6564a380f4a82c9","analyzedAt":"2026-08-07T00:01:08.491Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}