{"id":"74cf838e29effcb7","repo":"pypa/pip","slug":"unable-to-verify-server-certificate-for-s","errorCode":null,"errorMessage":"Unable to verify server certificate for %s","messagePattern":"Unable to verify server certificate for (.+?)","errorType":"http","errorClass":"CertificateError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/distlib/util.py","lineNumber":1542,"sourceCode":"            pass a connection class to do_open, but it doesn't actually check for\n            a class, and just expects a callable. As long as we behave just as a\n            constructor would have, we should be OK. If it ever changes so that\n            we *must* pass a class, we'll create an UnsafeHTTPSConnection class\n            which just sets check_domain to False in the class definition, and\n            choose which one to pass to do_open.\n            \"\"\"\n            result = HTTPSConnection(*args, **kwargs)\n            if self.ca_certs:\n                result.ca_certs = self.ca_certs\n                result.check_domain = self.check_domain\n            return result\n\n        def https_open(self, req):\n            try:\n                return self.do_open(self._conn_maker, req)\n            except URLError as e:\n                if 'certificate verify failed' in str(e.reason):\n                    raise CertificateError('Unable to verify server certificate '\n                                           'for %s' % req.host)\n                else:\n                    raise\n\n    #\n    # To prevent against mixing HTTP traffic with HTTPS (examples: A Man-In-The-\n    # Middle proxy using HTTP listens on port 443, or an index mistakenly serves\n    # HTML containing a http://xyz link when it should be https://xyz),\n    # you can use the following handler class, which does not allow HTTP traffic.\n    #\n    # It works by inheriting from HTTPHandler - so build_opener won't add a\n    # handler for HTTP itself.\n    #\n    class HTTPSOnlyHandler(HTTPSHandler, HTTPHandler):\n\n        def http_open(self, req):\n            raise URLError('Unexpected HTTP request on what should be a secure '\n                           'connection: %s' % req)","sourceCodeStart":1524,"sourceCodeEnd":1560,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/distlib/util.py#L1524-L1560","documentation":"Raised by HTTPSHandler.https_open() when an HTTPS request fails with a URLError whose reason contains 'certificate verify failed'. distlib re-wraps this as a ssl.CertificateError (subclass of ValueError) named 'Unable to verify server certificate for <host>', indicating the server's TLS certificate could not be validated against the configured CA bundle or hostname.","triggerScenarios":"Configuring a PackageIndex/HTTPSHandler with ca_certs pointing at a missing/expired CA bundle, connecting to an index URL with a self-signed or expired certificate, a system clock skew invalidating cert validity, or missing root CAs on the OS.","commonSituations":"Corporate proxies with custom CAs not in the trust store, stale pip/distlib ca_certs, air-gapped environments, expired Let's Encrypt certs, or container images without ca-certificates installed.","solutions":["Update the system CA store (e.g. 'apt-get install --reinstall ca-certificates' / 'update-ca-certificates').","Point ca_certs at the correct PEM bundle (e.g. certifi's cacert.pem or your org's bundle).","Fix system clock skew (NTP) so cert validity periods are evaluated correctly.","As a last resort on trusted networks, disable verification explicitly rather than letting it fail silently, and document the risk."],"exampleFix":"// before\nindex = PackageIndex(..., ca_certs='/missing/bundle.pem')\n// after\nimport certifi\nindex = PackageIndex(..., ca_certs=certifi.where())","handlingStrategy":"validation","validationCode":"import os, ssl\n\ndef ca_bundle_is_usable(ca_certs):\n    if not ca_certs or not os.path.exists(ca_certs):\n        return False\n    try:\n        ctx = ssl.create_default_context(cafile=ca_certs)\n        ctx.get_ca_certs()  # forces load\n        return True\n    except ssl.SSLError:\n        return False\n\ndef safe_index(url, ca_certs):\n    if not ca_bundle_is_usable(ca_certs):\n        raise ValueError('CA bundle missing or invalid: %r' % ca_certs)\n    # proceed to build PackageIndex/HTTPSHandler with ca_certs","typeGuard":null,"tryCatchPattern":"from ssl import CertificateError\ntry:\n    opener.open(req)\nexcept CertificateError as e:\n    if 'Unable to verify server certificate' in str(e):\n        refresh_ca_bundle()  # update ca-certificates / certifi\n        # then retry once; do NOT silently disable verification in production\n        opener.open(req)\n    else:\n        raise","preventionTips":["Keep the OS CA store and certifi up to date.","Point ca_certs at a verified PEM bundle and validate it loads before use.","Sync the system clock via NTP so certificate validity windows are correct.","For corporate CAs, add the root to the trust store rather than disabling verification."],"tags":["network","ssl","tls","certificate","security","packaging"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}