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.
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.