Skip to content

fix: strip connection-specific headers from HTTP/2 requests - #935

Open
lennartschoch wants to merge 1 commit into
benoitc:masterfrom
lennartschoch:fix/strip-connection-headers-h2
Open

fix: strip connection-specific headers from HTTP/2 requests#935
lennartschoch wants to merge 1 commit into
benoitc:masterfrom
lennartschoch:fix/strip-connection-headers-h2

Conversation

@lennartschoch

Copy link
Copy Markdown

Hit this moving an Elixir app onto hackney 4. As soon as ALPN picked h2, every request to one API started failing with {error, protocol_error} and nothing reached the server.

Turned out the client sets Connection: keep-alive in its default headers, which is fine in HTTP/1.1 and banned in h2 (RFC 9113 §8.2.2). The h2 layer is doing the right thing here — validate_outbound_request/1 rejects the header block and replies protocol_error before anything is written. The problem is that normalize_headers/1 only strips Host, so the header gets that far in the first place.

Since hackney picks the protocol itself via ALPN, the caller has no way to know which set of rules applies, so it can't really be the caller's job to leave these out. Host is already dropped there for the same kind of reason (:authority carries it), so this just extends it to the other five. TE is left alone since it's allowed with the value trailers and the h2 layer checks that separately.

rebar3 eunit is green, 1099 tests. The three new ones in test/hackney_http2_connection_headers_tests.erl fail without the change with {error, protocol_error} — one for Connection on its own, one for all five in mixed casing, and one checking ordinary headers still get through so the filter isn't over-eager.

RFC 9113 8.2.2 bans connection, keep-alive, proxy-connection,
transfer-encoding and upgrade, and the h2 layer refuses to send a block
containing one, so the request fails with protocol_error before it reaches
the socket. They are legal in HTTP/1.1 and the caller cannot know which
protocol ALPN picked, so drop them next to Host rather than failing requests
that are valid for hackney's own API.
@benoitc benoitc self-assigned this Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants