What changed in urllib3 from 1 to 2

9 releases numbered after 1.26.20 up to and including 2.7.0, stable releases only. 1.26.20 and 2.7.0 are the newest stable releases of 1 and 2 we track; this page follows them as new ones ship.

56 changes across 9 releases

Added 14

2.6.1

  • Restore previously removed HTTPResponse.getheaders() and HTTPResponse.getheader() methods

2.6.0

  • Enable retrieval, deletion, and membership testing in HTTPHeaderDict using bytes keys
  • Add host and port information to string representations of HTTPConnection
  • Add support for Python 3.14 free-threading builds explicitly

2.5.0

  • Added support for the compression.zstd module that is new in Python 3.14
  • Added support for version 0.5 of hatch-vcs

2.4.0

  • Added verify_flags option to create_urllib3_context with a default of VERIFY_X509_PARTIAL_CHAIN and VERIFY_X509_STRICT for Python 3.13+

2.3.0

  • Added HTTPResponse.shutdown() to stop any ongoing or future reads for a specific response by calling shutdown(SHUT_RD) on the underlying socket
  • Added support for JavaScript Promise Integration on Emscripten to enable more efficient WebAssembly requests and streaming
  • Added the proxy_is_tunneling property to HTTPConnection and HTTPSConnection
  • Added pickling support to NewConnectionError and NameResolutionError

2.2.3

  • Added support for Python 3.13
  • Added a probing mechanism for determining whether a given target origin supports HTTP/2 via ALPN
  • Added support for sending a request body with HTTP/2
Changed 9

2.7.0

  • Used FutureWarning instead of DeprecationWarning for better visibility of deprecation notices
  • Bumped minimum supported pyOpenSSL version to 19.0.0

2.6.3

  • Treat Retry-After times greater than 6 hours as 6 hours by default

2.6.0

  • Change the zstd extra to install backports.zstd instead of zstandard on Python 3.13 and before
  • Improve the performance of content decoding by optimizing BytesQueueBuffer class

2.4.0

  • Updated exceptions to save and restore more properties during the pickle/serialization process
  • Applied PEP 639 by specifying the license fields in pyproject.toml

2.2.3

  • Excluded Transfer-Encoding: chunked from HTTP/2 request body
  • Added version checking for h2 usage, now only accepting supported h2 major version 4.x.x
Fixed 20

2.7.0

  • Fixed HTTPResponse.read(amt=None) ignoring decompressed data buffered from previous partial reads
  • Fixed HTTPResponse.read() caching only part of response after partial read when cache_content=True
  • Fixed HTTPResponse.stream() and HTTPResponse.read_chunked() to handle amt=0
  • Updated _TYPE_BODY type alias to include missing Iterable[str] for chunked request bodies
  • Fixed LocationParseError when paths resembling schemeless URIs were passed to HTTPConnectionPool.urlopen()
  • Fixed BaseHTTPResponse.readinto() type annotation to accept memoryview in addition to bytearray

2.6.3

  • Fixed urllib3.connection.VerifiedHTTPSConnection on Emscripten

2.6.2

  • HTTPResponse.read_chunked() now properly handles leftover data in the decoder's buffer when reading compressed chunked responses

2.6.0

  • Fix redirect handling in urllib3.PoolManager when an integer is passed for the retries parameter
  • Fix HTTPConnectionPool when used in Emscripten with no explicit port
  • Fix handling of SSLKEYLOGFILE with expandable variables

2.5.0

  • Raised exception for HTTPResponse.shutdown on a connection already released to the pool
  • Fixed incorrect CONNECT statement when using an IPv6 proxy with connection_from_host where it would not be wrapped in []

2.4.0

  • Fixed a bug with partial reads of streaming data in Emscripten

2.3.0

  • Fixed debug logs rendering HTTP version as "HTTP/11" instead of "HTTP/1.1"

2.2.3

  • Fixed the default encoding of chunked request bodies to be UTF-8 instead of ISO-8859-1
  • Fixed ResourceWarning on CONNECT with Python < 3.11.4 by backporting CPython fix
  • Adjusted tolerance for floating-point comparison on Windows to avoid flakiness in CI
  • Fixed a crash where certain standard library hash functions were absent in restricted environments
  • Fixed mypy error when adding to HTTPConnection.default_socket_options
Removed 5

2.7.0

  • Removed support for end-of-life Python 3.9
  • Removed support for end-of-life PyPy3.10

2.6.0

  • Remove the HTTPResponse.getheaders() method in favor of HTTPResponse.headers
  • Remove the HTTPResponse.getheader(name, default) method in favor of HTTPResponse.headers.get(name, default)

2.3.0

  • Removed support for Python 3.8
Security 8

2.7.0

  • Fixed decompression-bomb safeguards bypass when HTTPResponse.drain_conn() was called after partial decompression
  • Fixed decompression-bomb safeguards bypass during second HTTPResponse.read(amt=N) or HTTPResponse.stream(amt=N) call with Brotli decompression
  • Fixed HTTP pools created using ProxyManager.connection_from_url to strip sensitive headers specified in Retry.remove_headers_on_redirect when redirecting to a different host

2.6.3

  • Fixed a security issue where decompression-bomb safeguards of the streaming API were bypassed when HTTP redirects were followed (CVE-2026-21441, GHSA-38jv-5279-wg99)

2.6.0

  • Fixed a security issue where streaming API could improperly handle highly compressed HTTP content leading to excessive resource consumption even when a small amount of data was requested (CVE-2025-66471)
  • Fixed a security issue where an attacker could compose an HTTP response with virtually unlimited links in the Content-Encoding header, potentially leading to denial of service by exhausting system resources during decoding, limiting the number of allowed chained encodings to 5 (CVE-2025-66418)

2.5.0

  • Pool managers now properly control redirects when retries is passed
  • Redirects are now controlled by urllib3 in the Node.js runtime

Original release notes, newest first

The list above is our reading of these notes; the originals from urllib3 are here, one fold per release.

2.7.0
🚀 urllib3 is fundraising for HTTP/2 support

urllib3 is raising ~$40,000 USD to release HTTP/2 support and ensure long-term sustainable maintenance of the project after a sharp decline in financial support. If your company or organization uses Python and would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and thousands of other projects please consider contributing financially to ensure HTTP/2 support is developed sustainably and maintained for the long-haul.

Thank you for your support.

Security

Addressed high-severity security issues. Impact was limited to specific use cases detailed in the accompanying advisories; overall user exposure was estimated to be marginal.

  • Decompression-bomb safeguards of the streaming API were bypassed:

    1. When HTTPResponse.drain_conn() was called after the response had been read and decompressed partially. (Reported by @Cycloctane)
    2. During the second HTTPResponse.read(amt=N) or HTTPResponse.stream(amt=N) call when the response was decompressed using the official Brotli library. (Reported by @kimkou2024)

    See GHSA-mf9v-mfxr-j63j for details.

  • HTTP pools created using ProxyManager.connection_from_url did not strip sensitive headers specified in Retry.remove_headers_on_redirect when redirecting to a different host. (GHSA-qccp-gfcp-xxvc reported by @christos-spearbit)

Deprecations and Removals
Bugfixes

View originalPermalink

2.6.3
🚀 urllib3 is fundraising for HTTP/2 support

urllib3 is raising ~$40,000 USD to release HTTP/2 support and ensure long-term sustainable maintenance of the project after a sharp decline in financial support. If your company or organization uses Python and would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and thousands of other projects please consider contributing financially to ensure HTTP/2 support is developed sustainably and maintained for the long-haul.

Thank you for your support.

Changes

View originalPermalink

2.6.2
🚀 urllib3 is fundraising for HTTP/2 support

urllib3 is raising ~$40,000 USD to release HTTP/2 support and ensure long-term sustainable maintenance of the project after a sharp decline in financial support. If your company or organization uses Python and would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and thousands of other projects please consider contributing financially to ensure HTTP/2 support is developed sustainably and maintained for the long-haul.

Thank you for your support.

Changes

View originalPermalink

2.6.1
🚀 urllib3 is fundraising for HTTP/2 support

urllib3 is raising ~$40,000 USD to release HTTP/2 support and ensure long-term sustainable maintenance of the project after a sharp decline in financial support. If your company or organization uses Python and would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and thousands of other projects please consider contributing financially to ensure HTTP/2 support is developed sustainably and maintained for the long-haul.

Thank you for your support.

Changes
  • Restore previously removed HTTPResponse.getheaders() and HTTPResponse.getheader() methods. (#3731)

View originalPermalink

2.6.0
🚀 urllib3 is fundraising for HTTP/2 support

urllib3 is raising ~$40,000 USD to release HTTP/2 support and ensure long-term sustainable maintenance of the project after a sharp decline in financial support. If your company or organization uses Python and would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and thousands of other projects please consider contributing financially to ensure HTTP/2 support is developed sustainably and maintained for the long-haul.

Thank you for your support.

Security
  • Fixed a security issue where streaming API could improperly handle highly compressed HTTP content ("decompression bombs") leading to excessive resource consumption even when a small amount of data was requested. Reading small chunks of compressed data is safer and much more efficient now. (CVE-2025-66471 reported by @Cycloctane, 8.9 High, GHSA-2xpw-w6gg-jr37)
  • Fixed a security issue where an attacker could compose an HTTP response with virtually unlimited links in the Content-Encoding header, potentially leading to a denial of service (DoS) attack by exhausting system resources during decoding. The number of allowed chained encodings is now limited to 5. (CVE-2025-66418 reported by @illia-v, 8.9 High, GHSA-gm62-xv2j-4w53)

[!IMPORTANT]

  • If urllib3 is not installed with the optional urllib3[brotli] extra, but your environment contains a Brotli/brotlicffi/brotlipy package anyway, make sure to upgrade it to at least Brotli 1.2.0 or brotlicffi 1.2.0.0 to benefit from the security fixes and avoid warnings. Prefer using urllib3[brotli] to install a compatible Brotli package automatically.
  • If you use custom decompressors, please make sure to update them to respect the changed API of urllib3.response.ContentDecoder.
Features
  • Enabled retrieval, deletion, and membership testing in HTTPHeaderDict using bytes keys. (#3653)
  • Added host and port information to string representations of HTTPConnection. (#3666)
  • Added support for Python 3.14 free-threading builds explicitly. (#3696)
Removals
  • Removed the HTTPResponse.getheaders() method in favor of HTTPResponse.headers. Removed the HTTPResponse.getheader(name, default) method in favor of HTTPResponse.headers.get(name, default). (#3622)
Bugfixes
  • Fixed redirect handling in urllib3.PoolManager when an integer is passed for the retries parameter. (#3649)
  • Fixed HTTPConnectionPool when used in Emscripten with no explicit port. (#3664)
  • Fixed handling of SSLKEYLOGFILE with expandable variables. (#3700)
Misc
  • Changed the zstd extra to install backports.zstd instead of zstandard on Python 3.13 and before. (#3693)
  • Improved the performance of content decoding by optimizing BytesQueueBuffer class. (#3710)
  • Allowed building the urllib3 package with newer setuptools-scm v9.x. (#3652)
  • Ensured successful urllib3 builds by setting Hatchling requirement to ≥ 1.27.0. (#3638)

View originalPermalink

2.5.0
🚀 urllib3 is fundraising for HTTP/2 support

urllib3 is raising ~$40,000 USD to release HTTP/2 support and ensure long-term sustainable maintenance of the project after a sharp decline in financial support. If your company or organization uses Python and would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and thousands of other projects please consider contributing financially to ensure HTTP/2 support is developed sustainably and maintained for the long-haul.

Thank you for your support.

Security issues

urllib3 2.5.0 fixes two moderate security issues:

  • Pool managers now properly control redirects when retries is passed — CVE-2025-50181 reported by @sandumjacob (5.3 Medium, GHSA-pq67-6m6q-mj2v)
  • Redirects are now controlled by urllib3 in the Node.js runtime — CVE-2025-50182 (5.3 Medium, GHSA-48p4-8xcf-vxj5)

Features

  • Added support for the compression.zstd module that is new in Python 3.14. See PEP 784 for more information. (#3610)
  • Added support for version 0.5 of hatch-vcs (#3612)

Bugfixes

  • Raised exception for HTTPResponse.shutdown on a connection already released to the pool. (#3581)
  • Fixed incorrect CONNECT statement when using an IPv6 proxy with connection_from_host. Previously would not be wrapped in []. (#3615)

View originalPermalink

2.4.0
🚀 urllib3 is fundraising for HTTP/2 support

urllib3 is raising ~$40,000 USD to release HTTP/2 support and ensure long-term sustainable maintenance of the project after a sharp decline in financial support. If your company or organization uses Python and would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and thousands of other projects please consider contributing financially to ensure HTTP/2 support is developed sustainably and maintained for the long-haul.

Thank you for your support.

Features

  • Applied PEP 639 by specifying the license fields in pyproject.toml. (#3522)
  • Updated exceptions to save and restore more properties during the pickle/serialization process. (#3567)
  • Added verify_flags option to create_urllib3_context with a default of VERIFY_X509_PARTIAL_CHAIN and VERIFY_X509_STRICT for Python 3.13+. (#3571)

Bugfixes

  • Fixed a bug with partial reads of streaming data in Emscripten. (#3555)

Misc

  • Switched to uv for installing development dependecies. (#3550)
  • Removed the multiple.intoto.jsonl asset from GitHub releases. Attestation of release files since v2.3.0 can be found on PyPI. (#3566)

View originalPermalink

2.3.0
🚀 urllib3 is fundraising for HTTP/2 support

urllib3 is raising ~$40,000 USD to release HTTP/2 support and ensure long-term sustainable maintenance of the project after a sharp decline in financial support for 2023. If your company or organization uses Python and would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and thousands of other projects please consider contributing financially to ensure HTTP/2 support is developed sustainably and maintained for the long-haul.

Thank you for your support.

Features
Bugfixes
Deprecations and Removals

Full Changelog: https://github.com/urllib3/urllib3/compare/2.2.3...2.3.0

View originalPermalink

2.2.3
🚀 urllib3 is fundraising for HTTP/2 support

urllib3 is raising ~$40,000 USD to release HTTP/2 support and ensure long-term sustainable maintenance of the project after a sharp decline in financial support for 2023. If your company or organization uses Python and would benefit from HTTP/2 support in Requests, pip, cloud SDKs, and thousands of other projects please consider contributing financially to ensure HTTP/2 support is developed sustainably and maintained for the long-haul.

Thank you for your support.

Features
  • Added support for Python 3.13. (#3473)
Bugfixes
  • Fixed the default encoding of chunked request bodies to be UTF-8 instead of ISO-8859-1. All other methods of supplying a request body already use UTF-8 starting in urllib3 v2.0. (#3053)
  • Fixed ResourceWarning on CONNECT with Python < 3.11.4 by backporting https://github.com/python/cpython/issues/103472. (`#3252)
  • Adjust tolerance for floating-point comparison on Windows to avoid flakiness in CI (#3413)
  • Fixed a crash where certain standard library hash functions were absent in restricted environments. (#3432)
  • Fixed mypy error when adding to HTTPConnection.default_socket_options. (#3448)
HTTP/2 (experimental)

HTTP/2 support is still in early development.

  • Excluded Transfer-Encoding: chunked from HTTP/2 request body (#3425)
  • Added version checking for h2 (https://pypi.org/project/h2/) usage. Now only accepting supported h2 major version 4.x.x. (#3290)
  • Added a probing mechanism for determining whether a given target origin supports HTTP/2 via ALPN. (#3301)
  • Add support for sending a request body with HTTP/2 (#3302)

Full Changelog: https://github.com/urllib3/urllib3/compare/2.2.2...2.2.3

View originalPermalink