A few days ago I suddenly remembered that HTTP/3 is a thing and decided to look up how to get it running on my server, such as on this very blog that you are reading now.

I'm running a bunch of services terminated by Nginx as a reverse proxy, so thats the place I had to focus on.

If you search the web for "nginx http3" you will quickly come across their announcement blog post as well as the docs for the ngx_http_v3_module module.

The first step is getting a supported build of Nginx. Nginx only supports HTTP/3 in version 1.25 and above. This server is still running Ubuntu 24.04, for which Canonical only shipped version v1.24. Darn. (FYI Ubuntu 25.04 apparently ships v1.26.)

Many Linux distros do this very annoying thing where they get all the software they want to package up and freeze it before launch and never update it again except by the distro maintainers occasionally backporting fixes. If you want the actual latest version from the vendors, you usually have to go to them yourself.

In this case, I went straight to the source and added Nginx's own apt feed. Installing this version got me v1.28.

Next, I updated my config according to the above docs. Annoyingly this never worked. If I only wanted HTTP/3 for one virtual server it worked, but as soon as I tried to enable HTTP/3 for a second one it kept complaining about a duplicate listen directive.

After much trial and error it seems that the key (for me at least) was to omit reuseport from the listen directive. Although the docs say to use listen 443 quic reuseport that keeps breaking for me. Here's the config that works for me:

listen 443 ssl;
listen [::]:443 ssl;
http2 on;

listen 443 quic;
listen [::]:443 quic;
http3 on;

add_header Alt-Svc 'h3=":443"; ma=86400';

That Alt-Svc header is important, it's what lets HTTP/1.1 and HTTP/2 connections know that there is a HTTP/3 service available to try.

And lastly, make sure to allow UDP port 443 (yes, UDP) through. If you have a network firewall (e.g. from your cloud provider) make sure to allow it there as well, not just on your host firewall.

The Web Inspector in Safari showing under the Network tab that the request to blog.yaakov.online was performed with Protocol h3.
h3 protocol as demonstrated by Safari's Web Inspector

And badabing badaboom, welcome to HTTP/3.0.