{"record":{"id":"596ad64fddd2664e","repo":"pypa/pip","slug":"ssl-verification-failed","errorCode":"ssl-verification-failed","errorMessage":"Failed to establish a secure connection to {host} while fetching {url}","messagePattern":"Failed to establish a secure connection to (.+?) while fetching (.+?)","errorType":"exception","errorClass":"SSLVerificationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/network/utils.py","lineNumber":180,"sourceCode":"    Note: requests.ConnectionError is the parent class of\n          requests.ProxyError, requests.SSLError, and requests.ConnectTimeout\n          so these errors are also handled here.\n    \"\"\"\n    url = redact_auth_from_url(url)\n    raw_hostname = urlsplit(url).hostname or urlsplit(url).netloc\n    reason = error.args[0] if error.args else error\n\n    # NewConnectionError is a subclass of TimeoutError for some reason...\n    if isinstance(reason, urllib3.exceptions.TimeoutError) and not isinstance(\n        reason, urllib3.exceptions.NewConnectionError\n    ):\n        # A bare timeout error can occur during non-streamed responses. Don't\n        # ask me how.\n        _raise_timeout_error(reason, url, raw_hostname, timeout)\n    if isinstance(reason, urllib3.exceptions.SSLError):\n        # A bare SSL error can occur during non-streamed responses, after the\n        # initial connection and TLS handshake have completed.\n        raise SSLVerificationError(url, raw_hostname, reason)\n\n    # At this point, all errors should be wrapped in MaxRetryError.\n    if not isinstance(reason, urllib3.exceptions.MaxRetryError):\n        raise ConnectionFailedError(url, raw_hostname, reason)\n\n    max_retry_error = reason\n    assert isinstance(max_retry_error.pool, urllib3.connectionpool.HTTPConnectionPool)\n    host = max_retry_error.pool.host\n    proxy = max_retry_error.pool.proxy\n    # Narrow the reason further to the specific error from the last retry.\n    reason = max_retry_error.reason\n\n    if isinstance(reason, urllib3.exceptions.SSLError):\n        raise SSLVerificationError(url, host, reason)\n    if isinstance(reason, urllib3.exceptions.TimeoutError) and not isinstance(\n        reason, urllib3.exceptions.NewConnectionError\n    ):\n        _raise_timeout_error(reason, url, host, timeout)","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/network/utils.py#L162-L198","documentation":"Raised as SSLVerificationError (the bare, non-MaxRetryError path) when a urllib3.exceptions.SSLError occurs during a non-streamed response, after the TLS handshake. It means certificate verification against the host failed and TLS could not be established.","triggerScenarios":"Server presents a self-signed, expired, or untrusted certificate; CA bundle missing or out of date; MITM proxy injecting its own cert; system clock skewed so notBefore/notAfter checks fail; TLS version/cipher mismatch.","commonSituations":"Corporate TLS-intercepting proxies; stale certifi/ca-certificates; air-gapped environments with private CAs; container images with old CA bundles.","solutions":["Update CA roots: pip install --upgrade certifi, or update OS ca-certificates.","Point pip at the correct CA bundle with --cert corporate-ca.pem.","Configure the corporate proxy's CA properly; fix system time if skewed.","Only as a last resort, use --trusted-host to bypass verification for that host (insecure)."],"exampleFix":"# before\npip install pkg   # MITM proxy with untrusted CA\n\n# after\npip install --cert /etc/ssl/corporate-ca.pem pkg","handlingStrategy":"validation","validationCode":"import ssl, certifi\n\ndef trust_store_ok(host: str) -> bool:\n    ctx = ssl.create_default_context(cafile=certifi.where())\n    try:\n        with ctx.wrap_socket(socket.create_connection((host, 443)), server_hostname=host):\n            return True\n    except ssl.SSLError:\n        return False","typeGuard":null,"tryCatchPattern":"from pip._internal.exceptions import SSLVerificationError\n\ntry:\n    run_pip_install([\"-i\", url, \"pkg\"])\nexcept SSLVerificationError:\n    run_pip_install([\"--cert\", \"/etc/ssl/private-ca.pem\", \"-i\", url, \"pkg\"])","preventionTips":["Keep certifi and OS ca-certificates current.","Register corporate/internal CAs in the system trust store.","Use --cert for non-standard CAs; avoid --trusted-host unless required."],"tags":["ssl","tls","certificate","verification"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}