[Pkg-nginx-maintainers] Bug#1126960: nginx: proxy_params should use $host instead of $http_host

Gabriel Corona gabriel.corona at free.fr
Mon Feb 9 20:47:44 GMT 2026


 > Changing $http_host with $host resolves the issue, and is more
 > futureproof.

I agree that using $host is more correct than $http_host.

Warning: however this could possibly introduce a regression if your 
backend application need to use the port information. $host does not 
include the port while $http_host typically does.

(Since NGINX 1.29.3, we can use $host$is_request_port$request_port but 
this not available in trixie.)

> Currently, HTTP/3 is broken with a HTTP/1.1 backend. As there is no Host
> header in HTTP/3 (the name is sent during the negociation and not as a
> header), the backend is refusing the request.

I'm wondering if this is not a bug in NGINX handling of HTTP/3 requests.

When I am submiting a HTTP/2 request with ":authority" and no "Host" 
header field (using Node.js http2 module), the $http_host variable is 
properly populated:

~~~
:method = GET
:path = /
:authority = 127.0.0.1:8000

:status: 200
server: nginx/1.29.3
date: Mon, 09 Feb 2026 20:46:29 GMT
content-type: application/octet-stream
content-length: 46

host = 127.0.0.1
http_host = 127.0.0.1:8000
~~~

Node.js code:

~~~
const http2 = require('node:http2');

const url = process.argv[2];
const authority = process.argv[3];
const host = process.argv[4];

const client = http2.connect(url);
const method = "GET";
const path = "/";
const params = {
   ':method': method,
   ':path': path,
};
if (authority != null && authority != "")
     params[":authority"] = authority;
if (host != null && host != "")
     params["host"] = host;

for (const k in params) {
   console.log(k + " = " + params[k]);
}
console.log("")

const req = client.request(params);

let data = ""
req.on('response', (headers, flags) => {
   for (const name in headers) {
     console.log(`${name}: ${headers[name]}`);
   }
});
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => {
   console.log(`\n${data}`);
   client.close();
   process.exit(0);
});
~~~

NGINX configuration:

~~~
server {
     listen 8000 default;
     http2 on;
     location / {
       return 200 "host = $host\r\nhttp_host = $http_host\r\n";
     }
}
~~~

Gabriel


-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://alioth-lists.debian.net/pipermail/pkg-nginx-maintainers/attachments/20260209/3b422be4/attachment.sig>


More information about the Pkg-nginx-maintainers mailing list