HTTP/3 runs HTTP over QUIC, a UDP-based transport with built-in TLS 1.3. It connects faster and copes better with packet loss and network changes than HTTP/2 over TCP, which helps mobile visitors most. Nginx supports it natively since version 1.25. This guide shows how to enable HTTP/3 in Nginx while keeping HTTP/2 as the fallback.
Before you start
- Nginx 1.25.0 or newer built with the
http_v3_module. The official nginx.org mainline and stable packages include it. - HTTPS already working with a valid certificate.
- Background on the protocols: HTTP/2 and HTTP/3 explained. On cPanel hosting with LiteSpeed, HTTP/3 is handled by the server: LiteSpeed HTTP/3.
Check your Nginx build
nginx -V 2>&1 | tr ' ' '\n' | grep -E 'http_v3|version'You need --with-http_v3_module in the output. Older distro packages may lack it; install from the nginx.org repository instead.
Configure the server block
server {
listen 443 ssl;
listen [::]:443 ssl;
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
http2 on;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Alt-Svc 'h3=":443"; ma=86400' always;
add_header QUIC-Status $http3 always;
}listen 443 quicopens the UDP listener;listen 443 sslkeeps TCP for HTTP/1.1 and HTTP/2.reuseportmay appear on only one server block per address:port. Other server blocks use plainlisten 443 quic;.Alt-Svctells browsers that HTTP/3 is available on UDP 443. Browsers always make the first visit over TCP, then switch on later requests.- TLS 1.3 is required for QUIC.
Optional QUIC settings
quic_retry on;
ssl_early_data on;
quic_gso on;quic_retryvalidates client addresses, a small defence against spoofed floods.ssl_early_dataenables 0-RTT resumption. Early data can be replayed, so only allow it if your app treats GET as safe; Nginx exposes$ssl_early_dataso the backend can reject risky requests.quic_gsouses segmentation offload on supported kernels to cut CPU.
Open UDP 443 in the firewall
- UFW:
sudo ufw allow 443/udp - firewalld:
sudo firewall-cmd --permanent --add-port=443/udp && sudo firewall-cmd --reload - Also check any provider-level firewall or security group.
This is the step people miss most. With UDP blocked, browsers silently stay on HTTP/2 and nothing looks broken.
Reload and verify
sudo nginx -t && sudo systemctl reload nginx- Confirm the UDP socket:
sudo ss -ulpn | grep ':443' - Check the header:
curl -sI https://example.com/ | grep -i alt-svc - If your curl is built with HTTP/3:
curl --http3-only -sI https://example.com/ - In Chrome or Firefox DevTools → Network, enable the Protocol column and reload twice; requests should show
h3.
Troubleshooting
- "invalid parameter quic": Nginx is too old or built without http_v3_module.
- "duplicate listen options for 0.0.0.0:443":
reuseportused in more than one server block. - Protocol stays h2: UDP 443 blocked, Alt-Svc missing, or the browser has not yet retried. Some corporate networks block QUIC entirely; that is expected and fallback works.
- Behind a CDN: the CDN speaks HTTP/3 to visitors; your origin config does not matter for them.
FAQ: HTTP/3 in Nginx
Will enabling HTTP/3 break older browsers?
No. They keep using HTTP/2 or HTTP/1.1 over TCP.
Does HTTP/3 improve SEO?
Not directly, but faster loading on mobile can help Core Web Vitals.
Do I need a different certificate?
No. QUIC uses the same certificate as HTTPS.
