nginx
protocol_error
ai_generated
partial
upstream sent HTTP/2.0 response while reading response header from upstream
ID: nginx/upstream-sent-http-2-0-response-while-reading-response-header-from-upstream
80%Fix Rate
85%Confidence
1Evidence
2024-06-25First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| nginx 1.18.0 | active | — | — | — |
| nginx 1.20.0 | active | — | — | — |
| nginx 1.22.0 | active | — | — | — |
| nginx 1.24.0 | active | — | — | — |
Root Cause
Upstream server responded with HTTP/2 (HTTP/2.0) but nginx is configured to use HTTP/1.x for proxying, causing a protocol mismatch.
generic中文
上游服务器以HTTP/2(HTTP/2.0)响应,但nginx配置为使用HTTP/1.x进行代理,导致协议不匹配。
Official Documentation
https://nginx.org/en/docs/http/ngx_http_v2_module.htmlWorkarounds
-
80% success Configure nginx to proxy using HTTP/2 by setting proxy_http_version 2.0; (requires nginx compiled with HTTP/2 support and ngx_http_v2_module): location / { proxy_http_version 2.0; proxy_pass https://upstream; # Note: HTTPS required for HTTP/2 }
Configure nginx to proxy using HTTP/2 by setting proxy_http_version 2.0; (requires nginx compiled with HTTP/2 support and ngx_http_v2_module): location / { proxy_http_version 2.0; proxy_pass https://upstream; # Note: HTTPS required for HTTP/2 } -
75% success If the upstream is an HTTP/2 server, configure it to also support HTTP/1.1. For example, in a Node.js server using http2 module: const http2 = require('http2'); const http = require('http'); const server = http2.createServer(); server.on('stream', (stream, headers) => { stream.respond({ ':status': 200 }); stream.end('OK'); }); server.listen(8080); Add an HTTP/1.1 listener on a different port if needed.
If the upstream is an HTTP/2 server, configure it to also support HTTP/1.1. For example, in a Node.js server using http2 module: const http2 = require('http2'); const http = require('http'); const server = http2.createServer(); server.on('stream', (stream, headers) => { stream.respond({ ':status': 200 }); stream.end('OK'); }); server.listen(8080); Add an HTTP/1.1 listener on a different port if needed. -
70% success Use a load balancer like HAProxy that can convert HTTP/2 to HTTP/1.1: frontend http-in bind *:80 default_backend servers backend servers server upstream1 10.0.0.1:8080 proto h2 HAProxy can terminate HTTP/2 and forward as HTTP/1.1 to nginx.
Use a load balancer like HAProxy that can convert HTTP/2 to HTTP/1.1: frontend http-in bind *:80 default_backend servers backend servers server upstream1 10.0.0.1:8080 proto h2 HAProxy can terminate HTTP/2 and forward as HTTP/1.1 to nginx.
中文步骤
Configure nginx to proxy using HTTP/2 by setting proxy_http_version 2.0; (requires nginx compiled with HTTP/2 support and ngx_http_v2_module): location / { proxy_http_version 2.0; proxy_pass https://upstream; # Note: HTTPS required for HTTP/2 }If the upstream is an HTTP/2 server, configure it to also support HTTP/1.1. For example, in a Node.js server using http2 module: const http2 = require('http2'); const http = require('http'); const server = http2.createServer(); server.on('stream', (stream, headers) => { stream.respond({ ':status': 200 }); stream.end('OK'); }); server.listen(8080); Add an HTTP/1.1 listener on a different port if needed.Use a load balancer like HAProxy that can convert HTTP/2 to HTTP/1.1: frontend http-in bind *:80 default_backend servers backend servers server upstream1 10.0.0.1:8080 proto h2 HAProxy can terminate HTTP/2 and forward as HTTP/1.1 to nginx.
Dead Ends
Common approaches that don't work:
-
90% fail
If the upstream only supports HTTP/2, forcing HTTP/1.1 will not change the upstream's response; the upstream will still send HTTP/2 responses.
-
95% fail
Buffer size does not affect protocol version negotiation.
-
85% fail
These headers are for WebSocket upgrades, not HTTP version negotiation.