HTTP3/QUIC doesn't work, again

Hello,

I had already started a thread about this issue, and with the help of
@sahsanu, we were able to resolve the problem and get HTTP/3 working properly.

Now, after months without making any changes, I checked and found that HTTP/3 is no longer working on my domains.

Upon double-checking, the configurations and templates are identical.
I really can’t figure out what the problem is.

I found this Nginx bug ( PSA: Using quic_bpf + reuseport will eventually drop HTTP/3 traffic - NGINX - NGINX Community Forum ), but I’m not sure if it’s related.
I tried a full restart of Nginx, but nothing has changed.

Thanks so much

If you updated Hestia, the upgrade rebuilt your users so the problem arised.

Show the output of this command:

grep -R quic /etc/nginx/conf.d/domains

Or if you don’t want to show many domains:

grep -R reuseport /etc/nginx/conf.d/domains

One and only one of your domains must have the listen IP:443 quic reuseport; directive.

grep -R quic /etc/nginx/conf.d/domains

/etc/nginx/conf.d/domains/luxuryconcept.stefanofattori.it.ssl.conf: listen 10.0.0.156:443 quic;
/etc/nginx/conf.d/domains/calcolatrapassoauto.it.ssl.conf: listen 10.0.0.156:443 quic;
/etc/nginx/conf.d/domains/stefanofattori.it.ssl.conf: listen 10.0.0.156:443 quic reuseport;

grep -R reuseport /etc/nginx/conf.d/domains

/etc/nginx/conf.d/domains/stefanofattori.it.ssl.conf: listen 10.0.0.156:443 quic reuseport;

You had sent me a script that automatically handled the reuseport.

Thanks

I see it is using HTTP/3:

mmmmh… interesting.

so why here do I can’t see the header Alt-Svc: h3=":443"; ma=86400

and here it says that it doesn’t use http3?

https://http3check.net/

HTTP Header Checker - Check HTTP Response Headers With curl | KeyCDN Tools

thanks

I don’t see the header too but it answers using HTTP/3

❯ curl-ech -IkL --http3 https://stefanofattori.it/
HTTP/3 200
server: nginx
date: Sat, 15 Aug 2026 18:22:43 GMT
content-type: text/html; charset=UTF-8
vary: accept-encoding
set-cookie: PHPSESSID=cb9seqmdq7qfmhkqk65jrb24nn; path=/
expires: Thu, 19 Nov 1981 08:52:00 GMT
cache-control: no-store, no-cache, must-revalidate
pragma: no-cache
link: <https://stefanofattori.it/wp-json/>; rel="https://api.w.org/"
link: <https://stefanofattori.it/wp-json/wp/v2/pages/10>; rel="alternate"; title="JSON"; type="application/json"
link: <https://stefanofattori.it/>; rel=shortlink
x-fastcgi-cache: HIT

Check whether the template you are using for your domains is adding the header.

#=========================================================================#

Default Web Domain Template

DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS


#=========================================================================#

server {
listen      %ip%:%web_ssl_port% quic;
listen      %ip%:%web_ssl_port% ssl;
server_name %domain_idn% %alias_idn%;
root        %sdocroot%;
index       index.php index.html index.htm;
access_log  /var/log/nginx/domains/%domain%.log combined;
access_log  /var/log/nginx/domains/%domain%.bytes bytes;
error_log   /var/log/nginx/domains/%domain%.error.log error;

    ssl_certificate     %ssl_pem%;
    ssl_certificate_key %ssl_key%;
    #Commented out ssl_stapling directives due to Lets Encrypt ending OCSP support in 2025
    #ssl_stapling        on;
    #ssl_stapling_verify on;

    # TLS 1.3 0-RTT anti-replay
    if ($anti_replay = 307) { return 307 https://$host$request_uri; }
    if ($anti_replay = 425) { return 425; }

    # Add support to HTTP/3
    add_header Alt-Svc 'h3=":$server_port"; ma=86400';

    include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*;

    location = /favicon.ico {
            log_not_found off;
            access_log off;
    }

    location = /robots.txt {
            try_files $uri $uri/ /index.php?$args;
            log_not_found off;
            access_log off;
    }

    location ~ /\.(?!well-known\/) {
            deny all;
            return 404;
    }

    location / {
            try_files $uri $uri/ /index.php?$args;

            location ~* ^.+\.(ogg|ogv|svg|svgz|swf|eot|otf|woff|woff2|mov|mp3|mp4|webm|flv|ttf|rss|atom|jpg|jpeg|gif|png|webp|ico|bmp|mid|midi|wav|rtf|css|js|jar)$ {
                    expires 30d;
                    fastcgi_hide_header "Set-Cookie";
            }

            location ~* /(?:uploads|files)/.*.php$ {
                    deny all;
                    return 404;
            }

            location ~ [^/]\.php(/|$) {
                    try_files $uri =404;

                    include /etc/nginx/fastcgi_params;

                    fastcgi_index index.php;
                    fastcgi_param HTTP_EARLY_DATA $rfc_early_data if_not_empty;
                    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                    fastcgi_param HTTP_HOST $host;

                    fastcgi_pass %backend_lsnr%;

                    include %home%/%user%/conf/web/%domain%/nginx.fastcgi_cache.conf*;

                    if ($request_uri ~* "/wp-admin/|/wp-json/|wp-.*.php|xmlrpc.php|index.php|/store.*|/cart.*|/my-account.*|/checkout.*") {
                            set $no_cache 1;
                    }

                    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash|PHPSESSID") {
                            set $no_cache 1;
                    }

                    add_header X-FastCGI-Cache $upstream_cache_status;
            }
    }

    location /error/ {
            alias %home%/%user%/web/%domain%/document_errors/;
    }

    location /vstats/ {
            alias   %home%/%user%/web/%domain%/stats/;
            include %home%/%user%/web/%domain%/stats/auth.conf*;
    }

    include /etc/nginx/conf.d/phpmyadmin.inc*;
    include /etc/nginx/conf.d/phppgadmin.inc*;
    include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;

}

Yes, same template, I never changed it.

In /usr/local/hestia/data/templates/web/nginx/php-fpm

And your domains are using it?

grep -R Alt-Svc /etc/nginx/conf.d/domains/

If they are using it:

nginx -t && systemctl restart nginx

/etc/nginx/conf.d/domains/luxuryconcept.stefanofattori.it.ssl.conf: add_header Alt-Svc 'h3=":$server_port"; ma=86400';
/etc/nginx/conf.d/domains/calcolatrapassoauto.it.ssl.conf: add_header Alt-Svc 'h3=":$server_port"; ma=86400';
/etc/nginx/conf.d/domains/stefanofattori.it.ssl.conf: add_header Alt-Svc 'h3=":$server_port"; ma=86400';

confirmed.



nginx -t && systemctl restart nginx
nginx: [warn] "ssl_stapling" ignored, no OCSP responder URL in the certificate "/home/stefano/conf/web/demoluxuryconcept.stefanofattori.it/ssl/demoluxuryconcept.stefanofattori.it.pem"
nginx: [warn] "ssl_stapling" ignored, no OCSP responder URL in the certificate "/home/stefano-admin/conf/web/vps-oci.stefanofattori.it/ssl/vps-oci.stefanofattori.it.pem"
nginx: [warn] "ssl_stapling" ignored, no OCSP responder URL in the certificate "/home/stefano/conf/mail/stefanofattori.it/ssl/stefanofattori.it.pem"
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

same

Weird, I don’t know why it’s not adding the header.

Are you using Nginx only or Nginx + Apache2?

Only NGINX

Show me the complete conf:

cat /etc/nginx/conf.d/domains/stefanofattori.it.ssl.conf

Ok, I missed this in the curl output:

x-fastcgi-cache: HIT

Looks like you added an add_header directive in a location block. If that’s the case, Nginx is removing the header added in the server block. Remove that header, or add the Alt-Svc header to the location where you added the X-FastCGI-Cache header.

I removed x-fastcgi-cache: HIT, I just needed it to find out whether the FastCGI cache actually worked.

Thank you so much, you’re always so helpful!