Skip to content

Conversation

@benoitc
Copy link
Owner

@benoitc benoitc commented Jan 19, 2026

Summary

Filter out the Host header when preparing HTTP/2 requests. HTTP/2 uses the :authority pseudo-header instead, and having both causes {stream_error, protocol_error} on strict HTTP/2 implementations.

Problem

hackney 2.0.0-beta.1 HTTP/2 requests were failing on Google servers with:

{error, {stream_error, protocol_error}}

Root cause: hackney was sending both Host header AND :authority pseudo-header in HTTP/2 HEADERS frames. While RFC 7540 allows Host for compatibility, Google's strict implementation rejects requests with both.

Solution

Filter out Host header in normalize_headers/1 when preparing HTTP/2 headers. The :authority pseudo-header already contains the same host information.

Testing

Verified working with:

  • www.google.com
  • oauth2.googleapis.com
  • storage.googleapis.com
  • nghttp2.org (still works)
  • httpbin.org (still works)

All 848 existing tests pass.

HTTP/2 uses the :authority pseudo-header instead of the Host header.
Having both Host and :authority headers causes protocol_error on strict
HTTP/2 implementations like Google's servers.

This change filters out the Host header in normalize_headers() when
preparing HTTP/2 requests, since the :authority pseudo-header already
contains the same information.

Fixes HTTP/2 compatibility with:
- www.google.com
- *.googleapis.com (oauth2, storage, aiplatform, etc.)
- Other strict HTTP/2 server implementations

References:
- RFC 7540 Section 8.1.2.3: "The :authority pseudo-header field includes
  the authority portion of the target URI"
@benoitc benoitc merged commit 01e97d9 into master Jan 19, 2026
5 checks passed
@benoitc benoitc deleted the fix/http2-host-header-google branch January 19, 2026 14:55
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