Opened 8 months ago

Closed 8 months ago

#1538 closed defect (invalid)

gRPC upstreams cannot use dynamic HPACK

Reported by: swolter.google.com@… Owned by:
Priority: major Milestone:
Component: other Version: 1.13.x
Keywords: Cc:
uname -a:
nginx -V: 1.13.10

Description

"upstream sent invalid http2 table index: 64 while reading response header from upstream,"

gRPC uses the HPACK header compression (https://tools.ietf.org/html/rfc7541), which allows for dynamic header compression by assigning each key/value pair an ID in an HPACK table. There is a static, pre-shared part of the HPACK table (values 0 .. 60), and a dynamic part. When a gRPC upstream uses a header for the first time, it sends "literal header with incremental indexing" (header name/value + id), and afterwards sends only the id ("indexed header").

nginx has the static HPACK values compiled in, but errors out on any attempt of the upstream to set a dynamic value (> 61). The client will only receive a 502. For example, any golang gRPC server is incompatible with nginx because the upstream will set content-type/application-grpc, which is not in the static HPACK table.

The offending code is https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_grpc_module.c#L2626, which hardcodes the static table.

Change History (1)

comment:1 Changed 8 months ago by mdounin

  • Resolution set to invalid
  • Status changed from new to closed

nginx explicitly announces that it does not support dynamic header compression by sending the SETTINGS_HEADER_TABLE_SIZE value set to 0, see here. Any attempt of an upstream server to use indexes from the dynamic range is a bug in the upstream server (note that at least grpc-go implementation is known to be buggy, see commit log in 2713b2dbf5bb).

Note: See TracTickets for help on using tickets.