Skip to content

Releases: benoitc/hackney

4.2.0

03 Jun 21:57
1d19996

Choose a tag to compare

Added

  • IPv6 for HTTP/3. The family connect option (inet | inet6) is forwarded to QUIC, which resolves DNS and races addresses with Happy Eyeballs (RFC 8305). IPv6 literals such as https://[::1]/ work too.
  • 0-RTT and session resumption for HTTP/3. Session tickets are cached per {host, port, transport} and replayed on the next connection; a bodyless one-shot request is then sent as 0-RTT, otherwise the ticket gives a resumed handshake. Controlled by the zero_rtt option, with an explicit session_ticket taking precedence. New hackney_h3 helpers: early_data_accepted/1, get_session_ticket/1, wait_session_ticket/2.

Fixed

  • Recover from an expired cross-signed root instead of failing the handshake (e.g. Let's Encrypt's ISRG Root X2 cross-signed by the expired ISRG Root X1), across HTTP/1.1, HTTP/2, HTTP/3 and WebTransport. A genuinely expired leaf or intermediate still fails, and partial chains keep working.
  • HTTP/3 connections from the pool now apply ssl_options (cacerts, insecure) that previously did not reach the QUIC layer.
  • A pooled connection that stops between checkout and the request call no longer leaks exit:{normal, _} / exit:noproc to the caller; request, body and streaming calls return {error, closed} instead (#861).
  • A proxy host given as an atom (e.g. localhost) or a binary is accepted again for the plain, connect and socks5 proxy tuples instead of being silently ignored (#858).

Dependencies

  • quic 1.4.5 -> 1.6.3.
  • h2 0.6.1 -> 0.8.0.
  • webtransport 0.2.6 -> 0.3.1.

hackney 4.1.0

29 May 21:24

Choose a tag to compare

WebTransport client. Drop-in addition alongside the WebSocket API, no breaking changes.

Added

  • WebTransport client API (hackney:wt_connect/1,2, wt_send/2, wt_recv/1,2, wt_setopts/2, wt_close/1,2), mirroring the WebSocket ws_* API so code switches by swapping the ws_ prefix for wt_. Runs over HTTP/3 (default) or HTTP/2. One session multiplexes many streams (wt_open_stream/2, wt_stream_send/3,4, wt_stream_recv/2,3, wt_close_stream/2, wt_reset_stream/3, wt_stop_sending/3) plus unreliable datagrams (wt_send_datagram/2) and wt_session_info/1. No custom wire framing, so it interoperates with any WebTransport server. Caller path and headers are checked for CR/LF/NUL and a buffer cap bounds unread data. See the WebTransport Guide.

Dependencies

  • Add webtransport 0.2.6.

Full changelog: https://github.com/benoitc/hackney/blob/master/NEWS.md

hackney 4.0.3

28 May 07:48
0570bfb

Choose a tag to compare

OTP 29 support and HTTP/3 server-certificate verification. Drop-in upgrade from 4.0.2, no API changes.

Security

  • HTTP/3 now verifies the server certificate. quic 1.4.4 authenticates the server by default; hackney passes the request's insecure option and any configured CA (cacerts/cacertfile in ssl_options) through to the QUIC connection, so verification can be disabled or pointed at a custom trust store. Without a configured CA, quic uses its default trust store.

Changed

  • Replace the deprecated catch Expr form with try ... catch so hackney compiles cleanly on OTP 29.

Dependencies

  • Bump quic to 1.4.5 (fixes server-cert chain validation when the server sends an extra cross-sign above the anchored intermediate).
  • Bump h2 to 0.6.1 (OTP 29 deprecated-catch fix).

Full changelog: https://github.com/benoitc/hackney/blob/master/NEWS.md

hackney 4.0.2

25 May 16:40

Choose a tag to compare

Bug-fix release. Drop-in upgrade from 4.0.1, no API changes.

Bug Fixes

  • Fix an intermittent pool crash when a server closes a pooled keep-alive connection during checkout (#850). The checkout now tolerates the set_owner race and falls through to a fresh connection instead of crashing on a bad match, and an async ownership handoff to an already-closed pooled connection stops it promptly so the pool drops it from rotation.
  • Expose hackney:body/1,2 and hackney:stream_body/1 again so the response body can be read after start_response/1 in streaming body mode (#849). The migration guide and examples referenced these but they were not exported. The getting-started guide and README were corrected as well.

Full changelog: https://github.com/benoitc/hackney/blob/master/NEWS.md

hackney 4.0.1

25 May 13:52

Choose a tag to compare

Security release. Fixes 9 reported vulnerabilities (4 high, 4 medium, 1 low) plus one hardening change across the HTTP/1.1, HTTP/2, HTTP/3, WebSocket, cookie and URL handling code. No API changes, so it is a drop-in upgrade from 4.0.0.

If you use hackney directly or through a library (HTTPoison, Tesla's hackney adapter, ExAws, and others), please upgrade.

Security

High

  • CVE-2026-47066 (GHSA-6cp8): infinite loop in the Alt-Svc response parser.
  • CVE-2026-47073 (GHSA-q8jg): unbounded WebSocket frame, message and handshake buffers.
  • CVE-2026-47074 (GHSA-jq4m): slow-drip OOM on buffered HTTP/3 responses.
  • CVE-2026-47071 (GHSA-gp9c): missing timeout on a proxy TLS upgrade.

Medium

  • CVE-2026-47076 (GHSA-pj7v): SSRF allowlist bypass via percent-encoded host.
  • CVE-2026-47072 (GHSA-f9vr): CR/LF injection in the WebSocket upgrade request.
  • CVE-2026-47075 (GHSA-j9wq): CR/LF injection in the request target.
  • CVE-2026-47070 (GHSA-h73q): cross-origin HTTP/3 redirect leaked Authorization and Cookie.

Low

  • CVE-2026-47069 (GHSA-mp55): CR/LF injection via cookie domain and path options.

Hardening

  • to_atom/1 no longer falls back to list_to_atom/1, removing an atom-leak path (GHSA-6rmf, no CVE assigned).

Dependencies

  • Bump quic to 1.4.3.
  • Bump h2 to 0.6.0.

Credits

Thanks to PJUllrich, Ganbagana and tepel-chen for the reports, and to maennchen for coordinating disclosure.

Full changelog: https://github.com/benoitc/hackney/blob/master/NEWS.md

hackney 4.0.0

16 Apr 07:07
322dd90

Choose a tag to compare

Hackney 4 trims the client down. The HTTP/2 and HTTP/3 stacks are now delegated to erlang_h2 and erlang_quic, so hackney no longer ships its own framing, HPACK / QPACK codecs, control streams or state machines. The HTTP/3 path is fully RFC 9114 compliant via quic_h3, with ALPN negotiation, Alt-Svc discovery (RFC 7838), and the same hackney:request/5 API as HTTP/1.1.

The bundled metrics subsystem is gone. In its place a Go-style middleware chain runs around hackney:request/1..5, configured per request with {middleware, [Fun, ...]} or globally via application:set_env(hackney, middleware, [...]). Users plug in prometheus, telemetry or anything else without hackney owning the policy. See the Middleware Guide and the HTTP/3 Guide.

Breaking

  • Removed hackney_metrics, hackney_metrics_backend, hackney_metrics_prometheus, hackney_metrics_dummy. The metrics_backend app env is no longer read. Migration recipes for prometheus and telemetry are in guides/middleware.md. Pool state is still observable through hackney_pool:get_stats/1.
  • HTTP/2 and HTTP/3 low-level message tags and modules moved to the new libraries. The user-facing hackney:request/5 API is unchanged.

What's new

  • Middleware chain (hackney_middleware): outermost-first composition, request rewrite, response rewrite, short-circuit, per-request or global config.
  • HTTP/3 via quic_h3: pure Erlang QUIC stack, no NIFs. ALPN-negotiated, opt-in with {protocols, [http3, http2, http1]} or application:set_env(hackney, default_protocols, [http3, http2, http1]).
  • Alt-Svc auto-discovery: server Alt-Svc headers are now parsed and cached on every response (HTTP/1.1, HTTP/2 and HTTP/3), so subsequent requests can upgrade to HTTP/3 transparently. Honors clear and merges multiple Alt-Svc headers per RFC 7230 §3.2.2.
  • HTTP/2 connection-pooling stability fixes for sustained concurrent load (#836).

Deps

  • h2 0.4.0
  • quic 1.0.0

Full changelog: https://github.com/benoitc/hackney/blob/4.0.0/NEWS.md

3.2.1

01 Mar 14:17

Choose a tag to compare

Bug Fixes

  • Fix recv_timeout option being ignored for pooled connections (#832)
  • Fix off-by-one error in HPACK decoding (#831)
  • Fix invalid match in handle_h2_frame/2 for HTTP/2 window updates (#829)
  • Fix binary syntax in EDoc comment to fix XML parsing error

3.2.0

21 Feb 20:04

Choose a tag to compare

Refactor

  • Replace all cowlib modules with hackney-native implementations
  • Remove src/libs/ directory (all modules moved to src/)

Performance

  • HTTP/2 state machine optimizations:
    • Stream caching for recently accessed streams
    • gb_sets for lingering streams (O(log N) vs O(N) lookups)
    • IOList accumulation for header fragments
  • HPACK and QPACK header compression with O(1) static table lookups
  • WebSocket: use rand:bytes/1 instead of crypto:strong_rand_bytes/1 for mask keys

Added

  • h2spec HTTP/2 compliance testing (95% pass rate - 139/146 tests)
    • h2spec_server.erl: Minimal HTTP/2 server for compliance testing
    • h2spec_SUITE.erl: CT suite for running h2spec tests
    • Makefile target: make h2spec-test
  • HTTP/3 E2E tests against real servers
    • hackney_http3_e2e_SUITE.erl: Tests against Cloudflare, Google, quic.tech
    • Makefile targets: make http3-e2e-test, make all-e2e-test
  • HTTP/2 machine benchmarks (hackney_http2_machine_bench.erl)

Bug Fixes

  • Fix HTTP/2 flow control for body sending (use send_or_queue_data/4)
  • Fix async 204/304/HEAD responses not sending done message
  • Fix unknown HTTP/2 frame types not being ignored (RFC 7540 4.1)
  • Fix HTTP/2 frame size validation

3.1.2

21 Feb 02:21

Choose a tag to compare

Dependencies

  • Bump quic dependency to 0.10.1

3.1.1

20 Feb 08:44

Choose a tag to compare

Bug Fixes

  • Fix HTTP/3 Fin flag handling for HEAD requests and responses without body
  • Bump quic dependency to 0.7.1 (fixes packet number reconstruction)

Added

  • Add TLS options support in hackney_quic (verify, cacerts, cacertfile, SNI)
  • Add redirect following in hackney_h3 (follow_redirect, max_redirect options)
  • Add HTTP/3 integration and redirect test suites (36 new tests)