curl can speak every HTTP version from 1.0 to 3, but which one it uses depends on flags, your build’s compiled features, and what the server offers. Forcing the wrong version — or assuming a feature is compiled in when it is not — leads to confusing failures. This reference lists each version flag with its negotiation behavior, transport and support requirements.
How it works
Over HTTPS, curl negotiates the protocol during the TLS handshake using ALPN:
it advertises the versions it supports and the server picks the highest it also
supports, usually landing on HTTP/2 where available and HTTP/1.1 otherwise. The
explicit flags override this. --http1.1 pins the universally supported baseline;
--http2 requests HTTP/2 via ALPN and falls back to 1.1 if the server declines;
--http2-prior-knowledge skips negotiation and assumes cleartext h2c, failing if
the server is not actually an HTTP/2 endpoint.
HTTP/3 is different: it runs over QUIC, a UDP-based transport that is always
encrypted, so it is HTTPS-only. --http3 tries QUIC first and falls back to TCP
on failure, while --http3-only forces HTTP/3 with no fallback. Both require a
curl built against a QUIC backend such as ngtcp2 or quiche.
Flag reference
| Flag | Protocol | Transport | Fallback | Requires |
|---|---|---|---|---|
--http1.0 | HTTP/1.0 | TCP | None | (always built in) |
--http1.1 | HTTP/1.1 | TCP | None | (always built in) |
--http2 | HTTP/2 via ALPN | TCP (TLS) | HTTP/1.1 | nghttp2 in build |
--http2-prior-knowledge | HTTP/2 cleartext (h2c) | TCP | None (fails if not h2c) | nghttp2 in build |
--http3 | HTTP/3 | QUIC (UDP) | TCP (HTTP/2 or 1.1) | QUIC backend in build |
--http3-only | HTTP/3 | QUIC (UDP) | None (fails if no QUIC) | QUIC backend in build |
Diagnosing common version negotiation failures
curl: option --http2: is unknown — your curl binary was not compiled with
nghttp2. On macOS, the system curl is often HTTP/1.1 only; install a full curl
via Homebrew (brew install curl). On Linux, install curl from the official
repository, which typically includes nghttp2.
curl: (1) Unsupported protocol with --http3 — no QUIC backend in the
build. HTTP/3-capable curl packages are not yet universal; compile from source
with ngtcp2 or quiche, or use a distribution that ships it.
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL when using
--http2-prior-knowledge on an HTTPS URL — prior-knowledge mode bypasses ALPN
and expects the server to already be speaking h2c (cleartext HTTP/2). Use
--http2 instead, which uses ALPN over TLS.
Connection times out when using --http3 — the server may not support HTTP/3,
or a firewall is blocking UDP traffic on port 443 (which QUIC uses). The
--http3 flag (without -only) falls back to TCP in this case; --http3-only
will simply fail.
Checking your build features
Before using a version flag, confirm your installed curl has it compiled in:
curl --version
Look at the Features line in the output. Relevant tokens:
HTTP2— nghttp2 is present;--http2and--http2-prior-knowledgework.HTTP3— a QUIC backend is present;--http3and--http3-onlywork.TLS— TLS support is compiled in (almost always true).
Example output excerpt:
curl 8.7.1 (x86_64-apple-darwin23.0)
Features: alt-svc AsynchDNS HTTP2 HTTPS-proxy IDN IPv6 Largefile libz NTLM SSL TLS-SRP UnixSockets
This build has HTTP2 but not HTTP3.
Tips and notes
Always confirm your build first with curl --version — the Features line lists
HTTP2 and HTTP3 only when the corresponding libraries were compiled in, and
the flags error out rather than downgrading silently if they are missing. Reserve
--http2-prior-knowledge for endpoints you know speak cleartext h2c, and use
--http3-only only when you specifically want to verify a QUIC path with no TCP
fallback masking a problem.