Test Nginx HTTP/3 with ngtcp2

Test Nginx HTTP/3 with ngtcp2
11/17/2025 •

We’ll build the ngtcp2 example client using the wolfSSL TLS backend (straightforward on Ubuntu), plus nghttp3 for HTTP/3. Then we’ll hit your server (e.g., localhost:8443) and verify QUIC/H3.

Colorful graphic featuring the text 'Nginx+ HTTP3' with a dynamic background of lines and colors

1) Install build deps

      sudo apt update
sudo apt install -y build-essential autoconf automake libtool pkg-config \
  cmake git libev-dev
    

2) Build and install wolfSSL (TLS)

      git clone --depth 1 -b v5.8.2-stable https://github.com/wolfSSL/wolfssl
cd wolfssl
autoreconf -i
# enable QUIC support & keylog export
./configure --prefix=$PWD/build --enable-all --enable-aesni --enable-harden \
  --disable-ech --enable-mlkem --enable-keylog-export
make -j"$(nproc)"
make install
cd ..

    

3) Build and install nghttp3 (HTTP/3 layer)

      git clone --recursive https://github.com/ngtcp2/nghttp3
cd nghttp3
autoreconf -i
./configure --prefix=$PWD/build --enable-lib-only
make -j"$(nproc)" check
make install
cd ..

    

4) Build ngtcp2 (QUIC) with wolfSSL

      git clone --recursive https://github.com/ngtcp2/ngtcp2
cd ngtcp2
autoreconf -i
PKG_CONFIG_PATH=$PWD/../wolfssl/build/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig \
  ./configure --with-wolfssl
make -j"$(nproc)" check

    
  • After a successful build, the example clients live under examples/. You’ll use examples/wsslclient (wolfSSL client) to talk H3. (This layout and commands come straight from the ngtcp2 README.) GitHub

5) Run the client against your Nginx

Assuming your Nginx H3 lab is on https://localhost:8443/ with a self-signed cert:

      cd ngtcp2
    

# Save a CA file if you have one; for a self-signed lab, use –insecure (-I) below.

# basic GET /

      examples/wsslclient localhost 8443 /
    

Nginx’s own HTTP/3 doc explicitly suggests validating with a console client like ngtcp2 before trying browsers. Nginx


6) Know it worked

  • The client prints the HTTP status/headers and transfer details.
  • On the server, add this log format once (then reload):
  • log_format quic ‘$remote_addr – $host “$request” $status h3=$http3’;
  • access_log /var/log/nginx/access.log quic;

You’ll see h3= filled for HTTP/3 requests.


7) Quick troubleshooting

  • No response / handshake fails
    • Ensure UDP 8443 (or 443) is listening/open:
    • ss -u -lpn | grep ‘:8443’   # or :443
    • sudo ufw allow 8443/udp
    • Verify your server block has:
    • listen 8443 quic reuseport;
    • listen 8443 ssl;  http2 on;
    • add_header Alt-Svc ‘h3=”:8443″; ma=86400’ always;
  • Cert errors: pass -I to wsslclient for self-signed; for real domains, use a proper cert and omit -I.
  • Build errors: make sure you ran autoreconf -i in each repo and set PKG_CONFIG_PATH like shown. (ngtcp2’s README lists the exact requirements and TLS backends supported.) GitHub

References

  • Nginx HTTP/3 docs (recommend using ngtcp2 first). Nginx
  • ngtcp2 README (build requirements, TLS backends, example clients). GitHub
  • curl HTTP/3 doc (if you later want an H3-capable curl build). Curl

https://nginx.org/index.html

https://www.wireshark.org/docs/relnotes

https://sanchitgurukul.com/basic-networking

https://sanchitgurukul.com/network-security

Disclaimer: This article may contain information that was accurate at the time of writing but could be outdated now. Please verify details with the latest vendor advisories or contact us at admin@sanchitgurukul.com.

Discover more from

Subscribe now to keep reading and get access to the full archive.

Continue reading