Skip to content

HTTP2 HEAD request fails when Content-Length header is non-zero #12747

@floom4

Description

@floom4

When doing a HEAD request to an HTTP2 origin, if the origin response contains "Content-Length" header with a non-zero value, it fails with 502 error.
This seems to be because of a check inside http2 handling which rejects request when "Content-Length" header and actual payload length don't match.

However, it is specified in rfc7540#section-8.1.2.6 that "A response that is defined to have no payload, as described in [RFC7230], Section 3.3.2, can have a non-zero content-length header field, even though no content is included in DATA frames."

The issue seems to be in includes/proxy/http2/Http2Stream.h in payload_length_is_valid_fuction which does not take this case into account

inline bool
Http2Stream::payload_length_is_valid() const
{
  uint32_t content_length = _receive_header.get_content_length();
  if (content_length != 0 && content_length != data_length) {
    Warning("Bad payload length content_length=%d data_legnth=%d session_id=%" PRId64, content_length,
            static_cast<int>(data_length), _proxy_ssn->connection_id());
  }
  return content_length == 0 || content_length == data_length;
}

Investigation data

Working GET query
floom@floom-pc:~$ curl -v https://my-test-delivery-service.ats.my-domain.com
...
< HTTP/2 200 
< server: nginx/1.24.0 (Ubuntu)
< date: Tue, 09 Dec 2025 17:29:37 GMT
< content-type: text/html
< content-length: 615
< last-modified: Fri, 14 Feb 2025 12:00:53 GMT
< etag: "67af3075-267"
< accept-ranges: bytes
< age: 0
< x-cache: skipped
< 
* TLSv1.2 (IN), TLS header, Supplemental data (23):
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to Inst1!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Failing HEAD query
floom@floom-pc:~$ curl -I https://my-test-delivery-service.ats.my-domain.com
HTTP/2 502 
date: Tue, 09 Dec 2025 17:21:51 GMT
cache-control: no-store
content-type: text/html
content-language: en
x-cache: skipped
content-length: 294
Same HEAD query directly to origin
floom@floom-pc:~$ curl -I http://192.168.1.150
HTTP/2 200 OK
server: nginx/1.24.0 (Ubuntu)
date: Tue, 09 Dec 2025 17:28:16 GMT
content-type: text/html
content-length: 615
last-modified: Fri, 14 Feb 2025 12:00:53 GMT
etag: "67af3075-267"
accept-ranges: bytes
Traffic server logs
[Dec  9 18:06:38.417] [ET_NET 15] WARNING: Bad payload length content_length=615 data_legnth=0 session_id=554
[Dec  9 18:06:38.417] [ET_NET 15] ERROR: HTTP/2 stream error code=0x01 client_ip=192.168.1.150 session_id=554 stream_id=3 recv data bad payload length

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions