{"id":250,"library":"urllib3","title":"urllib3","description":"urllib3 is a powerful, user-friendly HTTP client library for Python providing thread-safe connection pooling, client-side TLS/SSL verification, multipart file uploads, retry helpers, redirect handling, and support for gzip, deflate, brotli, and zstd content encoding. Current stable version is 2.6.3 (released 2025). The project follows an active release cadence with security patches, minor feature releases, and occasional major versions; the 2.x line requires Python >=3.9 and OpenSSL >=1.1.1.","status":"active","version":"2.6.3","language":"python","source_language":"en","source_url":"https://github.com/urllib3/urllib3","tags":["http","networking","connection-pooling","tls","ssl","requests","async-io"],"install":[{"cmd":"pip install urllib3","lang":"bash","label":"Standard"},{"cmd":"pip install urllib3[brotli]","lang":"bash","label":"With Brotli support"},{"cmd":"pip install urllib3[zstd]","lang":"bash","label":"With Zstandard support"},{"cmd":"pip install urllib3[socks]","lang":"bash","label":"With SOCKS proxy support"}],"dependencies":[{"reason":"Brotli content-encoding decompression (install via urllib3[brotli])","package":"brotli","optional":true},{"reason":"Alternative Brotli implementation for non-CPython runtimes","package":"brotlicffi","optional":true},{"reason":"Zstd content-encoding decompression on Python <=3.13 (install via urllib3[zstd])","package":"zstandard","optional":true},{"reason":"SOCKS proxy support (install via urllib3[socks])","package":"pysocks","optional":true},{"reason":"Mozilla CA bundle; not required — urllib3 2.x delegates cert verification to Python/OpenSSL by default, but useful for environments with no system CAs","package":"certifi","optional":true}],"imports":[{"note":"Primary interface for production use; manages connection pools across multiple hosts","symbol":"PoolManager","correct":"import urllib3\nhttp = urllib3.PoolManager()"},{"note":"Convenience shortcut backed by a module-global PoolManager; side effects are shared across all callers in the same process — prefer an explicit PoolManager instance in libraries and long-running services","symbol":"urllib3.request (top-level)","correct":"import urllib3\nresp = urllib3.request('GET', 'https://example.com')"},{"note":"Importing from connectionpool was accidental in v1.x and was removed in v2.0; always import from urllib3.connection","wrong":"from urllib3.connectionpool import VerifiedHTTPSConnection","symbol":"VerifiedHTTPSConnection","correct":"from urllib3.connection import VerifiedHTTPSConnection"},{"note":"DEFAULT_CIPHERS was removed in v2.0; urllib3 now delegates cipher selection to the system OpenSSL configuration","wrong":"from urllib3.util.ssl_ import DEFAULT_CIPHERS","symbol":"DEFAULT_CIPHERS","correct":"# Do not import DEFAULT_CIPHERS; urllib3 2.x uses system cipher list"},{"note":"Returned by PoolManager.request(); access body via resp.data (bytes) or resp.json(); use resp.stream() for chunked/streaming reads","symbol":"HTTPResponse","correct":"from urllib3.response import HTTPResponse"},{"note":"Pass a Retry instance to PoolManager(retries=...) or per-request; controls retry count, backoff, status codes, and redirect behaviour","symbol":"Retry","correct":"from urllib3.util.retry import Retry"},{"note":"Use Timeout(connect=2, read=5) for separate connect/read timeouts; passing a bare float sets both","symbol":"Timeout","correct":"from urllib3.util.timeout import Timeout"}],"quickstart":{"code":"import urllib3\nfrom urllib3.util.retry import Retry\nfrom urllib3.util.timeout import Timeout\n\n# Explicit PoolManager — preferred over the module-level urllib3.request() in\n# library code to avoid shared global state.\nhttp = urllib3.PoolManager(\n    timeout=Timeout(connect=3.0, read=10.0),\n    retries=Retry(total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504]),\n)\n\n# Simple GET — response body is bytes; call .json() for JSON payloads\nresp = http.request(\"GET\", \"https://httpbin.org/get\")\nprint(resp.status)          # 200\nprint(resp.json())          # parsed JSON dict\n\n# POST with form fields\nresp = http.request(\"POST\", \"https://httpbin.org/post\", fields={\"key\": \"value\"})\nprint(resp.status)\n\n# POST with JSON body (sets Content-Type: application/json automatically)\nresp = http.request(\"POST\", \"https://httpbin.org/post\", json={\"key\": \"value\"})\nprint(resp.json()[\"json\"])  # echoed back by httpbin\n\n# Streaming a large response\nresp = http.request(\"GET\", \"https://httpbin.org/stream-bytes/1024\", preload_content=False)\nfor chunk in resp.stream(32):\n    print(len(chunk), \"bytes\")\nresp.release_conn()\n","lang":"python","description":"Create an explicit PoolManager and make GET/POST requests with timeout and retry logic."},"warnings":[{"fix":"Upgrade the Python runtime (Lambda: use Python 3.10+), or pin urllib3<2 if the runtime cannot be changed.","message":"urllib3 v2.0 dropped Python 2.7 and 3.5–3.8 support and requires OpenSSL >=1.1.1. Environments compiled against older OpenSSL (e.g. AWS Lambda Python 3.9 runtime, Amazon Linux 2) will raise an ImportError or NotOpenSSLWarning on import.","severity":"breaking","affected_versions":"<2.0"},{"fix":"Import VerifiedHTTPSConnection from urllib3.connection; remove all references to DEFAULT_CIPHERS (urllib3 now uses the system cipher list).","message":"VerifiedHTTPSConnection, DEFAULT_CIPHERS, and several other symbols moved or were deleted in v2.0. Importing them from their old v1.x locations (e.g. urllib3.connectionpool.VerifiedHTTPSConnection, urllib3.util.ssl_.DEFAULT_CIPHERS) raises AttributeError/ImportError.","severity":"breaking","affected_versions":"<2.0"},{"fix":"Replace ssl_version=ssl.PROTOCOL_TLSv1_2 with ssl_minimum_version=ssl.TLSVersion.TLSv1_2 when constructing an SSLContext or calling create_urllib3_context().","message":"The ssl_version parameter (used to pin a specific TLS protocol version) was deprecated in 2.0 and removed as of v2.6.0. Passing it now raises a TypeError.","severity":"breaking","affected_versions":">=2.6.0"},{"fix":"Reissue certificates with a proper subjectAltName extension, or set cert_reqs='CERT_NONE' only for internal/test environments (never production).","message":"v2.0 dropped commonName certificate hostname verification; only subjectAltName is now accepted. Self-signed or legacy certs that only set CN (and not SAN) will fail TLS verification.","severity":"breaking","affected_versions":">=2.0"},{"fix":"Instantiate an explicit urllib3.PoolManager() and keep it as a long-lived object; pass it around rather than relying on the global shortcut.","message":"The module-level urllib3.request() function uses a hidden global PoolManager. In libraries or multi-threaded services, calling it shares cookies, connections, and retry state across all callers in the same process.","severity":"gotcha","affected_versions":">=2.0"},{"fix":"Pass preload_content=False to request(), then iterate with resp.stream(chunk_size) and always call resp.release_conn() when done.","message":"Responses with preload_content=True (the default) read the entire body into memory before returning. For large or streaming responses this can exhaust memory silently.","severity":"gotcha","affected_versions":">=1.0"},{"fix":"Upgrade to urllib3>=2.6.3 immediately.","message":"CVE-2026-21441 (GHSA-38jv-5279-wg99, CVSS 8.9): decompression-bomb safeguards in the streaming API were bypassed when HTTP redirects were followed. Fixed in 2.6.3.","severity":"gotcha","affected_versions":">=2.6.0,<2.6.3"}],"env_vars":null,"last_verified":"2026-05-12T12:21:10.992Z","next_check":"2026-06-25T00:00:00.000Z","problems":[{"fix":"Increase the number of retries or adjust the timeout settings for your PoolManager, and ensure the target server is accessible and responsive.\n```python\nimport urllib3\n\nhttp = urllib3.PoolManager(\n    retries=urllib3.Retry(total=5, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504]),\n    timeout=urllib3.Timeout(connect=2.0, read=5.0)\n)\ntry:\n    r = http.request('GET', 'http://example.com/resource', retries=3)\n    print(r.status)\nexcept urllib3.exceptions.MaxRetryError as e:\n    print(f\"Request failed after max retries: {e}\")\n```","cause":"The request failed multiple times (due to connection errors, timeouts, or server issues) and exhausted the configured number of retries.","error":"Max retries exceeded with url"},{"fix":"Ensure `certifi` is installed and up-to-date (`pip install --upgrade certifi`), and your `PoolManager` is configured to use it, or provide a custom CA bundle if necessary.\n```python\nimport urllib3\nimport certifi\n\nhttp = urllib3.PoolManager(\n    cert_reqs='CERT_REQUIRED',\n    ca_certs=certifi.where() # Ensures the latest CA certificates are used\n)\ntry:\n    r = http.request('GET', 'https://secure.example.com')\n    print(r.status)\nexcept urllib3.exceptions.SSLError as e:\n    print(f\"SSL Certificate Error: {e}\")\n```","cause":"urllib3 failed to verify the SSL certificate of the remote host, often due to missing or outdated CA certificates, an untrusted self-signed certificate, or a hostname mismatch.","error":"CERTIFICATE_VERIFY_FAILED"},{"fix":"Verify that the target host and port are correct, the server is running and accessible, and there are no network or firewall restrictions blocking the connection.\n```python\nimport urllib3\nimport socket\n\nhttp = urllib3.PoolManager()\ntry:\n    r = http.request('GET', 'http://invalid-host-or-port.com:9999') # Correct this URL\n    print(r.status)\nexcept (urllib3.exceptions.NewConnectionError, socket.gaierror) as e:\n    print(f\"Connection establishment failed: {e}\")\n    print(\"Please check the hostname, port, server status, and network connectivity.\")\n```","cause":"urllib3 was unable to establish a new TCP connection to the specified host and port, often due to the server being down, incorrect address, or network/firewall issues.","error":"Failed to establish a new connection"},{"fix":"Install the `urllib3` library using pip in your active Python environment.\n```bash\npip install urllib3\n```","cause":"The `urllib3` package is not installed in the Python environment currently being used or is not accessible in the `PYTHONPATH`.","error":"ModuleNotFoundError: No module named 'urllib3'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":6.2,"disk_size":"18.7M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":6.2,"disk_size":"22.5M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":6.2,"disk_size":"18.8M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":6.3,"disk_size":"20.4M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":6.2,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":6.2,"disk_size":"24M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":6.2,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":6.3,"disk_size":"21M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.31,"mem_mb":6.7,"disk_size":"20.7M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.32,"mem_mb":6.7,"disk_size":"24.4M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.31,"mem_mb":6.7,"disk_size":"20.8M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.31,"mem_mb":6.8,"disk_size":"22.5M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":6.7,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":6.7,"disk_size":"26M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":6.7,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.25,"mem_mb":6.8,"disk_size":"23M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":7,"disk_size":"12.5M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":7.1,"disk_size":"16.3M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":7,"disk_size":"12.6M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":7.2,"disk_size":"14.3M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":7,"disk_size":"13M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":7.1,"disk_size":"18M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":7,"disk_size":"13M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":7.2,"disk_size":"15M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":7.3,"disk_size":"12.2M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":7.3,"disk_size":"15.9M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":7.3,"disk_size":"12.3M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":7.4,"disk_size":"13.9M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":7.3,"disk_size":"13M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":7.3,"disk_size":"18M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":7.3,"disk_size":"13M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.25,"mem_mb":7.4,"disk_size":"14M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":5.6,"disk_size":"18.2M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":5.6,"disk_size":"21.9M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":5.6,"disk_size":"18.3M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.18,"mem_mb":6.2,"disk_size":"19.8M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":5.6,"disk_size":"19M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"brotli","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":6.1,"disk_size":"24M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"socks","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":5.6,"disk_size":"19M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"zstd","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":6,"disk_size":"20M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}