Releases: urllib3/urllib3
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:
- When
HTTPResponse.drain_conn()was called after the response had been read and decompressed partially. (Reported by @Cycloctane) - During the second
HTTPResponse.read(amt=N)orHTTPResponse.stream(amt=N)call when the response was decompressed using the official Brotli library. (Reported by @kimkou2024)
See GHSA-mf9v-mfxr-j63j for details.
- When
-
HTTP pools created using
ProxyManager.connection_from_urldid not strip sensitive headers specified inRetry.remove_headers_on_redirectwhen redirecting to a different host. (GHSA-qccp-gfcp-xxvc reported by @christos-spearbit)
Deprecations and Removals
- Used
FutureWarninginstead ofDeprecationWarningfor better visibility of existing deprecation notices. Rescheduled the removal of deprecated features to version 3.0. (#3763) - Removed support for end-of-life Python 3.9. (#3720)
- Removed support for end-of-life PyPy3.10. (#4979)
- Bumped the minimum supported pyOpenSSL version to 19.0.0. (#3777)
Bugfixes
- Fixed a bug where
HTTPResponse.read(amt=None)was ignoring decompressed data buffered from previous partial reads. (#3636) - Fixed a bug where
HTTPResponse.read()could cache only part of the response after a partial read whencache_content=True. (#4967) - Fixed
HTTPResponse.stream()andHTTPResponse.read_chunked()to handleamt=0. (#3793) - Updated
_TYPE_BODYtype alias to include missingIterable[str], matching the documented and runtime behavior of chunked request bodies. (#3798) - Fixed
LocationParseErrorwhen paths resembling schemeless URIs were passed toHTTPConnectionPool.urlopen(). (#3352) - Fixed
BaseHTTPResponse.readinto()type annotation to acceptmemoryviewin addition tobytearray, matching theio.RawIOBase.readintocontract and enabling use withio.BufferedReaderwithout type errors. (#3764)
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
- Fixed a security issue where decompression-bomb safeguards of the streaming API were bypassed when HTTP redirects were followed. (CVE-2026-21441 reported by @D47A, 8.9 High, GHSA-38jv-5279-wg99)
- Started treating
Retry-Aftertimes greater than 6 hours as 6 hours by default. (#3743) - Fixed
urllib3.connection.VerifiedHTTPSConnectionon Emscripten. (#3752)
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
- Fixed
HTTPResponse.read_chunked()to properly handle leftover data in the decoder's buffer when reading compressed chunked responses. (#3734)
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()andHTTPResponse.getheader()methods. (#3731)
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-Encodingheader, 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 usingurllib3[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
HTTPHeaderDictusing 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 ofHTTPResponse.headers. Removed theHTTPResponse.getheader(name, default)method in favor ofHTTPResponse.headers.get(name, default). (#3622)
Bugfixes
- Fixed redirect handling in
urllib3.PoolManagerwhen an integer is passed for the retries parameter. (#3649) - Fixed
HTTPConnectionPoolwhen used in Emscripten with no explicit port. (#3664) - Fixed handling of
SSLKEYLOGFILEwith expandable variables. (#3700)
Misc
- Changed the
zstdextra to installbackports.zstdinstead ofzstandardon Python 3.13 and before. (#3693) - Improved the performance of content decoding by optimizing
BytesQueueBufferclass. (#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)
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
retriesis 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.zstdmodule 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
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_flagsoption tocreate_urllib3_contextwith a default ofVERIFY_X509_PARTIAL_CHAINandVERIFY_X509_STRICTfor Python 3.13+. (#3571)
Bugfixes
- Fixed a bug with partial reads of streaming data in Emscripten. (#3555)
Misc
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
- Added
HTTPResponse.shutdown()to stop any ongoing or future reads for a specific response. It callsshutdown(SHUT_RD)on the underlying socket. This feature was sponsored by LaunchDarkly. (#2868) - Added support for JavaScript Promise Integration on Emscripten. This enables more efficient WebAssembly requests and streaming, and makes it possible to use in Node.js if you launch it as node
--experimental-wasm-stack-switching. (#3400) - Added the
proxy_is_tunnelingproperty toHTTPConnectionandHTTPSConnection. (#3285) - Added pickling support to
NewConnectionErrorandNameResolutionError. (#3480)
Bugfixes
- Fixed an issue in debug logs where the HTTP version was rendering as "HTTP/11" instead of "HTTP/1.1". (#3489)
Deprecations and Removals
- Removed support for Python 3.8. (#3492)
Full Changelog: 2.2.3...2.3.0
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 python/cpython#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: 2.2.2...2.2.3
1.26.20
🚀 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.
Changes
- Fixed a crash where certain standard library hash functions were absent in FIPS-compliant environments. (#3432)
- Replaced deprecated dash-separated setuptools entries in
setup.cfg. (#3461) - Took into account macOS setting
ECONNRESETinstead ofEPROTOTYPEin its newer versions. (#3416) - Backported changes to our tests and CI configuration from v2.x to support testing with CPython 3.12 and 3.13. (#3436)
Full Changelog: 1.26.19...1.26.20