# 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`
- **Domain:** nginx
- **Category:** protocol_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## 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.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| nginx 1.18.0 | active | — | — |
| nginx 1.20.0 | active | — | — |
| nginx 1.22.0 | active | — | — |
| nginx 1.24.0 | active | — | — |

## Workarounds

1. **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
}** (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
}
   ```
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.** (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.
   ```
3. **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.** (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.
   ```

## Dead Ends

- **** — 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. (90% fail)
- **** — Buffer size does not affect protocol version negotiation. (95% fail)
- **** — These headers are for WebSocket upgrades, not HTTP version negotiation. (85% fail)
