Using HTTP/3 with cURL is a fast way to confirm whether an HTTPS endpoint can actually complete a request over QUIC before that behavior is depended on in API checks, deployment validation, or synthetic probes. Protocol-specific testing matters when latency, UDP filtering, or transport policy can change whether a service stays reachable.
When a curl build includes QUIC support, --http3 tells curl to try HTTP/3 first while still allowing a fallback to HTTP/2 or HTTP/1.1 if the QUIC attempt fails quickly. --http3-only removes that fallback and turns the same request into a strict transport check, which is useful before automation or policy changes start requiring HTTP/3.
HTTP/3 availability depends on both the target and the curl build. Many packaged curl builds still omit the HTTP3 feature flag entirely, and some networks block or mangle UDP even when ordinary HTTPS over TCP works, so the safest flow is to confirm build support first and then test both negotiated protocol and strict-mode behavior against representative hosts. The published endpoint names below stay masked while preserving the verified negotiation and failure patterns.
Related: How to use HTTP/2 in cURL
Related: How to debug HTTP requests with verbose cURL output
Steps to use HTTP/3 with cURL:
- Check the local cURL feature list for HTTP/3 support before sending protocol-specific requests.
$ curl --version | grep '^Features:' Features: alt-svc AsynchDNS HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Largefile libz NTLM PSL SSL threadsafe UnixSockets zstd
Without HTTP3 in the Features line, --http3 and --http3-only cannot negotiate QUIC and a different curl build is required before continuing.
- Send a header request with --http3 so curl can try HTTP/3 first without giving up older HTTP versions.
$ curl --http3 --silent --show-error --head https://portal-edge.example.test/ HTTP/3 200 content-length: 18426 server: edge-proxy content-type: text/html; charset=utf-8 cache-control: max-age=60 alt-svc: h3=":443"; ma=86400
A response status line that starts with HTTP/3 confirms that the transfer used QUIC instead of a TCP-based fallback.
- Print only the negotiated protocol number when a script or health check needs a clean assertion.
$ curl --http3 --silent --show-error --output /dev/null --write-out '%{http_version}\n' https://portal-edge.example.test/ 3
Output 3 confirms successful HTTP/3 negotiation, while 2 or 1.1 shows that the request completed over an earlier HTTP version instead.
- Inspect verbose output when transport confirmation matters more than the response body.
$ curl --http3 --verbose --silent --show-error --output /dev/null https://portal-edge.example.test/ * Host portal-edge.example.test:443 was resolved. * IPv4: 192.0.2.24, 192.0.2.25 * Trying 192.0.2.24:443... ##### snipped ##### * using HTTP/3 * [HTTP/3] [0] OPENED stream for https://portal-edge.example.test/ * [HTTP/3] [0] [:method: GET] * [HTTP/3] [0] [:scheme: https] * [HTTP/3] [0] [:authority: portal-edge.example.test] * [HTTP/3] [0] [:path: /] > GET / HTTP/3
The using HTTP/3 line and the HTTP/3 stream metadata provide stronger proof of transport choice than the status line alone.
- Check fallback behavior against a host that does not currently negotiate HTTP/3 before relying on strict mode in automation.
$ curl --http3 --silent --show-error --output /dev/null --write-out '%{http_version}\n' https://legacy-www.example.test/ 1.1
A result such as 1.1 or 2 means the request still succeeded, but the target or network path did not complete HTTP/3 for that transfer.
- Force --http3-only against a known-compatible endpoint when the workflow must fail instead of falling back.
$ curl --http3-only --silent --show-error --head https://portal-edge.example.test/ HTTP/3 200 content-length: 18426 server: edge-proxy content-type: text/html; charset=utf-8 cache-control: max-age=60 alt-svc: h3=":443"; ma=86400
Strict mode is appropriate only after a safe --http3 test has already shown that the endpoint consistently negotiates HTTP/3.
- Use --http3-only against a non-compatible target to confirm the hard-failure behavior before embedding it in production checks.
$ curl --http3-only --silent --show-error --head https://legacy-www.example.test/ curl: (7) Failed to connect to legacy-www.example.test port 443 after 328 ms: Could not connect to server
--http3-only does not fall back to HTTP/2 or HTTP/1.1, so unsupported targets and UDP-blocked paths fail the transfer instead of silently downgrading it.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
