# What changed in urllib3

> 63 changes in urllib3 2 from its official release notes, upgrade guides and advisories: 12 breaking, 3 deprecations, 12 security, 4 new APIs and options. Each one cited. Sources checked 2026-10-18. HTML: https://unstale.sh/pypi/urllib3/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## urllib3 2

### Breaking changes

- A supported-length fingerprint containing non-hexadecimal characters now raises SSLError instead of binascii.Error. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- Forwarding through an HTTPS proxy no longer applies target SNI, assertions, or client credentials to proxy handshakes; the proxy SSL context and identity checks are respected. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- PoolManager no longer passes assert_hostname and assert_fingerprint parameters to HTTP connection pools. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- Retries of request bodies with tell() but no seek() now raise UnrewindableBodyError instead of ValueError. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- HTTP(S) host parsing now strictly enforces RFC 3986 syntax, rejects invalid host input, and normalizes percent-encoded octets according to RFC 3986. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- The minimum supported pyOpenSSL version is now 19.0.0. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- Support for end-of-life PyPy3.10 has been removed. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- Support for end-of-life Python 3.9 has been removed. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- Retry-After times greater than 6 hours are treated as 6 hours by default. (2.6.3) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.3)
- Custom decompressors must be updated to respect the changed API. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)
- Removed in favor of HTTPResponse.headers.get(name, default). (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)
- Removed in favor of HTTPResponse.headers. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)

### Security

- is_ipaddress() now detects non-standard IPv4 forms accepted by socket.connect, ensuring SSL certificate verification uses the correct mode for those addresses. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- HTTPS proxy TLS settings are no longer ignored or overridden by destination TLS settings. Configure proxy CA certificates and client certificates in proxy_ssl_context. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0), [security advisory](https://github.com/advisories/GHSA-8988-9CW3-XX77)
- Safeguards prevent potential security issues when proxy tunneling handles invalid characters in the proxy host and HTTP headers. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- urllib3: Chunked Deflate streaming can enter an infinite loop (2.8.0) — [security advisory](https://github.com/advisories/GHSA-GH4C-6FX4-QH6G)
- urllib3: HTTPResponse.stream()/read_chunked() buffers an unbounded chunk-size line into memory (2.8.0) — [security advisory](https://github.com/advisories/GHSA-VXQ7-64XX-V4GW)
- Fixed streaming API cases that bypassed decompression-bomb safeguards after partial reads or when using the official Brotli library. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0), [security advisory](https://github.com/advisories/GHSA-MF9V-MFXR-J63J)
- ProxyManager pools now strip sensitive headers specified in this setting when redirecting to a different host. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0), [security advisory](https://github.com/advisories/GHSA-QCCP-GFCP-XXVC)
- Fixed a security issue that bypassed streaming API decompression-bomb safeguards when following HTTP redirects. (2.6.3) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.3), [security advisory](https://github.com/advisories/GHSA-38JV-5279-WG99)
- Chained encodings are limited to 5 to prevent denial-of-service attacks that exhaust resources during decoding. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0), [security advisory](https://github.com/advisories/GHSA-GM62-XV2J-4W53)
- Reading small chunks of highly compressed content is safer and more efficient, preventing excessive resource consumption when only a small amount of data is requested. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0), [security advisory](https://github.com/advisories/GHSA-2XPW-W6GG-JR37)
- urllib3 allows an unbounded number of links in the decompression chain (2.6.0) — [security advisory](https://github.com/advisories/GHSA-GM62-XV2J-4W53)
- urllib3 streaming API improperly handles highly compressed data (2.6.0) — [security advisory](https://github.com/advisories/GHSA-2XPW-W6GG-JR37)

### Deprecations

- Using an empty collection for Retry.allowed_methods to retry any verb is deprecated. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- Removal of deprecated features has been rescheduled to version 3.0. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- Existing deprecation notices now use FutureWarning instead of DeprecationWarning for better visibility. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)

### New APIs and options

- urllib3.util.make_headers() now accepts a basic_auth_encoding parameter. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- urllib3.util.make_headers() now accepts a proxy_basic_auth_encoding parameter. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- The result of parse_url() now has an auth_decoded convenience property. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- The result of parse_url() now has an auth_decoded_joined convenience property. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)

### Performance

- Streamed response decoding is faster. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- Content decoding is faster due to an optimization to BytesQueueBuffer. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)

### Behavior and default changes

- The default pool queue class is resolved from the queue module after ConnectionPool instantiation, allowing late monkey-patching such as by gevent. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- String representations now include host and port information. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)
- Bytes keys can now be used to retrieve, delete, and test membership in HTTPHeaderDict. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)
- Support for Python 3.14 free-threading builds is now explicit. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)

### Tooling

- A test dependency group containing the minimum dependencies needed to run the test suite is available for downstream packagers. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)

### Fixes and other changes

- Handling of HTTP 303 redirects is fixed for requests with chunked or file-like bodies. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- URL fragments are stripped from absolute request targets before HTTPConnectionPool.urlopen() and HTTP proxy forwarding send requests. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- An invalid timeout argument on a pool created with block=True now raises ValueError instead of a misleading FullPoolError. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- Unread response data is discarded in 64 KiB chunks, matching the default amt used by HTTPResponse.stream(...). (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- Obsolete folded response header lines are replaced with spaces in accordance with RFC 9112, preventing raw CRLF sequences from appearing in header values such as Set-Cookie. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- Explicit :0 values are preserved instead of being replaced with default ports 80 or 443 across URL parsing, pool selection, proxy configuration, connection_from_url(), and HTTP/2 request authority. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- proxy_ssl_context now works with ProxyManager when use_forwarding_for_https=True. Passing ssl_context instead emits a FutureWarning and will raise an error in v3.0. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- Percent-encoded SOCKS proxy credentials are decoded before authentication with the proxy server. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- An AttributeError on Python built with OpenSSL 4+ is fixed when ssl.PROTOCOL_TLSv1 no longer exists. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- Certificate subject reading and encrypted private-key loading use cryptography APIs, avoiding DeprecationWarning from pyOpenSSL 26.3.0+. (2.8.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.8.0)
- The type annotation now accepts memoryview as well as bytearray, matching the io.RawIOBase.readinto contract and enabling use with io.BufferedReader without type errors. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- Fixed LocationParseError for paths resembling schemeless URIs passed to urlopen(). (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- Calling read with amt=None now includes decompressed data buffered from previous partial reads. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- With cache_content=True, read() now caches the complete response after a partial read. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- read_chunked() now handles amt=0. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- stream() now handles amt=0. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- The type alias now includes Iterable[str], matching documented and runtime behavior for chunked request bodies. (2.7.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.7.0)
- Fixed VerifiedHTTPSConnection on Emscripten. (2.6.3) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.3)
- Fixed read_chunked() to properly handle leftover data in the decoder's buffer when reading compressed chunked responses. (2.6.2) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.2)
- Restores the previously removed HTTPResponse.getheader() method. (2.6.1) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.1)
- Restores the previously removed HTTPResponse.getheaders() method. (2.6.1) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.1)
- Fixed use in Emscripten when no explicit port is provided. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)
- Handling of expandable variables is fixed. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)
- The zstd extra installs backports.zstd instead of zstandard on Python 3.13 and earlier. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)
- Redirect handling is fixed when an integer is passed for the retries parameter. (2.6.0) — [release notes](https://github.com/urllib3/urllib3/releases/tag/2.6.0)
