Using HTTP/2 with cURL is a direct way to confirm that an HTTPS endpoint really negotiates the newer transport before API checks, synthetic probes, or proxy policy start depending on it. A normal request is often enough to prove the protocol version in use, which keeps the check close to real client traffic.
For HTTPS URLs, cURL already offers HTTP/2 during the TLS ALPN negotiation when the local build and the server both support it, so a plain request can return HTTP/2 without any protocol flag. The --http2 option mainly matters when the request uses cleartext HTTP and needs an h2c upgrade attempt, while --http2-prior-knowledge skips that upgrade only for hosts that are already known to speak HTTP/2 directly.
This workflow still depends on both ends of the connection. A cURL build without the HTTP2 feature cannot use these options at all, a server or intermediary can still negotiate down to HTTP/1.1, and --http2-prior-knowledge on HTTPS changed in cURL 8.10.0 so it now offers only HTTP/2 in ALPN instead of both HTTP/2 and HTTP/1.1.
Related: How to use HTTP/3 with cURL
Related: How to debug HTTP requests with cURL
Steps to use HTTP/2 in cURL:
- Check the local cURL build for the HTTP2 feature before using protocol-specific flags.
$ curl --version curl 8.7.1 (x86_64-apple-darwin25.0) libcurl/8.7.1 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.12 nghttp2/1.68.0 Release-Date: 2024-03-27 Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL threadsafe UnixSockets
Look for HTTP2 in the Features line. Without it, --http2 and --http2-prior-knowledge cannot negotiate the protocol and a different cURL build is required.
- Send a simple HEAD request to an HTTPS endpoint and read the status line to confirm that cURL negotiated HTTP/2 automatically.
$ curl --silent --show-error --head https://curl.se/ HTTP/2 200 server: nginx/1.27.5 content-type: text/html last-modified: Wed, 22 Apr 2026 02:05:02 GMT etag: "2c81-65002f5b81d2b" ##### snipped #####
For HTTPS URLs, this is the normal starting point because cURL already offers HTTP/2 by default when the remote side supports it.
Related: How to send HEAD requests with cURL
- Print the negotiated protocol and final status in one line when a script or health check needs a clean assertion.
$ curl --silent --show-error --output /dev/null --write-out 'HTTP/%{http_version} %{response_code}\n' https://curl.se/ HTTP/2 200http_version reports the protocol actually used, so HTTP/2 200 confirms both the negotiated transport and the successful response in a script-friendly format.
- Ask a cleartext HTTP endpoint to upgrade to HTTP/2 when testing h2c support.
$ curl --http2 --silent --show-error --head http://nghttp2.org/httpbin/get HTTP/1.1 101 Switching Protocols Connection: Upgrade Upgrade: h2c HTTP/2 200 date: Wed, 22 Apr 2026 03:54:05 GMT content-type: application/json content-length: 150 ##### snipped #####
The initial 101 Switching Protocols response is the HTTP/1.1 upgrade handshake, and the second block is the real HTTP/2 response.
- Skip the Upgrade: round trip only when the target is already known to accept direct HTTP/2 on cleartext HTTP.
$ curl --http2-prior-knowledge --silent --show-error --head http://nghttp2.org/httpbin/get HTTP/2 200 date: Wed, 22 Apr 2026 03:54:14 GMT content-type: application/json content-length: 150 ##### snipped #####
Use --http2-prior-knowledge only with controlled targets. On HTTPS, it still negotiates through ALPN, and since cURL 8.10.0 it offers only HTTP/2 instead of both HTTP/2 and HTTP/1.1.
- Inspect verbose output when you need proof of the ALPN decision and the final request framing.
$ curl --http2 --verbose --silent --show-error --output /dev/null https://curl.se/ * Host curl.se:443 was resolved. * IPv4: 151.101.65.91, 151.101.193.91, 151.101.1.91, 151.101.129.91 * Trying 151.101.65.91:443... * Connected to curl.se (151.101.65.91) port 443 * ALPN: curl offers h2,http/1.1 ##### snipped ##### * ALPN: server accepted h2 * using HTTP/2 * [HTTP/2] [1] OPENED stream for https://curl.se/ * [HTTP/2] [1] [:method: GET] * [HTTP/2] [1] [:scheme: https] * [HTTP/2] [1] [:authority: curl.se] * [HTTP/2] [1] [:path: /] > GET / HTTP/2 < HTTP/2 200
The ALPN lines plus using HTTP/2 and GET / HTTP/2 are stronger transport proof than the status line alone when the protocol choice must be documented.
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.
