# Proxy\_params by default blocks reverse proxy for HTTP/3

**URL:** <https://community.nginx.org/t/proxy-params-by-default-blocks-reverse-proxy-for-http-3/6792>\
**Category:** NGINX\
**Tags:** quic, http3, reverse-proxy\
**Created:** [September 12, 2025, 8:37am UTC](https://community.nginx.org/t/proxy-params-by-default-blocks-reverse-proxy-for-http-3/6792 "2025-09-12T08:37:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![DorianCoding](https://drob5swvtjqxg.cloudfront.net/user_avatar/community.nginx.org/doriancoding/32/3137_2.png) [@DorianCoding](https://community.nginx.org/u/DorianCoding)\
**Post date:** [September 12, 2025, 8:37am UTC](https://community.nginx.org/t/proxy-params-by-default-blocks-reverse-proxy-for-http-3/6792/1 "2025-09-12T08:37:25Z")

</div>

_Please use this template for troubleshooting questions._

**My issue:**

By default, proxy\_params sent $http\_host to proxy servers and not $host. However only HTTP/1 and HTTP/1.1 is available as proxy\_pass.

**How I encountered the problem:**

If you use HTTP/3 in NGINX, there is no more Host: header in the request, as it is dealed during the TLS handshake. Therefore, proxies does not get Host: header which is however a requirement of HTTP/1.1 and reject with a 400 header Bad request without any logs.

**Solutions I’ve tried:**

The use by default of $host in proxy\_params would solve or a specific param to set it only for HTTP/3.

**Version of NGINX or NGINX adjacent software (e.g. NGINX Gateway Fabric): Nginx Debian 1.28.0**

**Deployment environment:**

**Minimal NGINX config to reproduce your issue (preferably running on [https://tech-playground.com/playgrounds/nginx](https://tech-playground.com/playgrounds/nginx) for ease of debugging, and if not as a code block):**

Default nginx with a HTTP/3 enabled and HTTP/1.1 proxy\_pass. Could not test on tech-playground as a certificate is compulsory.

Thank you.

---

<div class="post-metadata">

**Author:** ![alessandro](https://drob5swvtjqxg.cloudfront.net/user_avatar/community.nginx.org/alessandro/32/4836_2.png) [@alessandro](https://community.nginx.org/u/alessandro)\
**Post date:** [October 2, 2025, 10:25pm UTC](https://community.nginx.org/t/proxy-params-by-default-blocks-reverse-proxy-for-http-3/6792/2 "2025-10-02T22:25:56Z")

</div>

Hi @DorianCoding!

Your overall assessment is correct, but I am not entirely sure what you mean by `proxy_params`. Is that a file contained in your NGINX installation? If so, could you share the contents of the file and let us know where did you install NGINX from? There might be nothing we can tweak on our end to solve this issue 😕

---

<div class="post-metadata">

**Author:** ![liam](https://drob5swvtjqxg.cloudfront.net/user_avatar/community.nginx.org/liam/32/99_2.png) [@liam](https://community.nginx.org/u/liam)\
**Post date:** [October 3, 2025, 8:35am UTC](https://community.nginx.org/t/proxy-params-by-default-blocks-reverse-proxy-for-http-3/6792/3 "2025-10-03T08:35:49Z")

</div>

Two possible solutions:

1. Use `server_name` to define the $host variable
2. Use the hostname from TLS ($ssl\_server\_name)

If you need something conditional based on HTTP version then

```nginx
map $http3 $hostbyver {
    "" $host;
    default $ssl_server_name; # For HTTP/3 request, obtain from TLS handshake
}

server {
    listen …;
    location / {
        proxy_pass …;
        proxy_set_header Host $hostbyver;
    }
}

```

---

<div class="post-metadata">

**Author:** ![DorianCoding](https://drob5swvtjqxg.cloudfront.net/user_avatar/community.nginx.org/doriancoding/32/3137_2.png) [@DorianCoding](https://community.nginx.org/u/DorianCoding)\
**Post date:** [October 3, 2025, 9:52am UTC](https://community.nginx.org/t/proxy-params-by-default-blocks-reverse-proxy-for-http-3/6792/4 "2025-10-03T09:52:33Z")

</div>

Proxy\_params is the default file from Debian package:

```auto
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

```

Changing $http\_host to $host solves the problem. I think @liam solution could work as well, but maybe is more or less the same as $host. My question is also: why it is not implemented by default as nginx provides HTTP/3 on stable?

---

<div class="post-metadata">

**Author:** ![liam](https://drob5swvtjqxg.cloudfront.net/user_avatar/community.nginx.org/liam/32/99_2.png) [@liam](https://community.nginx.org/u/liam)\
**Post date:** [October 3, 2025, 10:25am UTC](https://community.nginx.org/t/proxy-params-by-default-blocks-reverse-proxy-for-http-3/6792/5 "2025-10-03T10:25:47Z")

</div>

> [@DorianCoding](#):
>
> why it is not implemented by default as nginx provides HTTP/3 on stable?

Your complaint is with Debian. They are packaging NGINX with opinionated params.

From the docs [Module ngx\_http\_proxy\_module](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header)

> An unchanged “Host” request header field can be passed like this:  
> `proxy_set_header Host $http_host;`  
> However, if this field is not present in a client request header then nothing will be passed. In such a case it is better to use the $host variable - its value equals the server name in the “Host” request header field or the primary server name if this field is not present:  
> `proxy_set_header Host $host;`

---

<div class="post-metadata">

**Author:** ![system](https://drob5swvtjqxg.cloudfront.net/user_avatar/community.nginx.org/system/32/19_2.png) [@system](https://community.nginx.org/u/system)\
**Post date:** [October 17, 2025, 6:44pm UTC](https://community.nginx.org/t/proxy-params-by-default-blocks-reverse-proxy-for-http-3/6792/6 "2025-10-17T18:44:30Z")

</div>

Closed on October 17, 2025, 6:44pm UTC

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.
