CURLOPT_HTTP_VERSION(3)

πŸ’… CURLOPT_HTTP_VERSION β€” ok bestie, let's pick an HTTP version ✨

So this is a page from the Library Functions Manual, and it's all about CURLOPT_HTTP_VERSION β€” the libcurl option that tells your handle which HTTP protocol version you wanna speak. Pull up a chair, this one's actually iconic.


🌸 SYNOPSIS 🌸

#include <curl/curl.h>

CURLcode curl_easy_setopt(CURL *handle, CURLOPT_HTTP_VERSION, long version);

✨ DESCRIPTION ✨

Okay so you pass in version β€” it's a long β€” and you set it to one of the values listed below. Each one is basically you politely asking libcurl to use that specific HTTP version. πŸ’–

lowkey important caveat: the HTTP version is just a request. libcurl still prioritizes reusing existing connections, so it might end up reusing a connection that's speaking an HTTP version you literally never asked for. It's giving "I hear you but I'm gonna do what I want." πŸ™ˆ

Here's the whole menu, bestie:

  • CURL_HTTP_VERSION_NONE β€” We genuinely do not care what version the library uses. libcurl uses whatever it thinks fit. Chill vibes only. πŸ¦‹
  • CURL_HTTP_VERSION_1_0 β€” Enforce HTTP 1.0 requests. Old school, no notes.
  • CURL_HTTP_VERSION_1_1 β€” Enforce HTTP 1.1 requests. The classic.
  • CURL_HTTP_VERSION_2_0 β€” Attempt HTTP 2 requests. If HTTP 2 can't be negotiated with the server, libcurl falls back to HTTP 1.1. No cap.
    • When libcurl uses HTTP/2 over HTTPS, it does not itself insist on TLS 1.2 or higher β€” even though that's literally required by the specification. If you want that version requirement, a user can add it with CURLOPT_SSLVERSION(3). 🫢
    • The alias CURL_HTTP_VERSION_2 was added to better reflect the actual protocol name. Cute little nickname, iykyk.
  • CURL_HTTP_VERSION_2TLS β€” Attempt HTTP 2 over TLS (HTTPS) only. libcurl falls back to HTTP 1.1 if HTTP 2 can't be negotiated with the HTTPS server. For clear text HTTP servers, libcurl uses 1.1. πŸŽ€
  • CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE β€” Issue non-TLS HTTP requests using HTTP/2 without the HTTP/1.1 Upgrade. This requires prior knowledge that the server supports HTTP/2 straight away β€” you gotta know, bestie. HTTPS requests still do HTTP/2 the standard way, with the negotiated protocol version in the TLS handshake.
    • Since 8.10.0, if this option is set for an HTTPS request, then the application layer protocol version (ALPN) offered to the server is only HTTP/2. Prior to that, both HTTP/1.1 and HTTP/2 were offered. Main character energy, honestly. πŸ‘‘
  • CURL_HTTP_VERSION_3 β€” (Added in 7.66.0) This option makes libcurl attempt to use HTTP/3 to the host given in the URL, with fallback to earlier HTTP versions if needed. So forgiving. πŸ’œ
  • CURL_HTTP_VERSION_3ONLY β€” (Added in 7.88.0) Setting this makes libcurl attempt to use HTTP/3 directly to the server given in the URL and does not downgrade to an earlier HTTP version if the server does not support HTTP/3. Periodt. No fallback, no backup plan. πŸ’€

πŸŽ€ DEFAULT πŸŽ€

The defaults have been through some eras, ngl:

  • Since curl 8.13.0: CURL_HTTP_VERSION_NONE
  • Since curl 7.62.0: CURL_HTTP_VERSION_2TLS
  • Before that: CURL_HTTP_VERSION_1_1

🌈 PROTOCOLS 🌈

This functionality affects http only. That's it. That's the whole vibe check.


⭐ EXAMPLE ⭐

int main(void)
{
  CURL *curl = curl_easy_init();
  if(curl) {
    CURLcode result;
    curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
    curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
    result = curl_easy_perform(curl);
    if(result == CURLE_HTTP_RETURNED_ERROR) {
      /* an HTTP response error problem */
    }
  }
}

Look at that. Immaculate. 😭


🧚 HISTORY 🧚

CURL_HTTP_VERSION_* enums became long types in 8.13.0. Prior to this version, a long cast was necessary when passed to curl_easy_setopt(3). So if you're on an older curl and it's complaining… yeah, that's why. πŸ™ˆ


πŸ¦‹ AVAILABILITY πŸ¦‹

Added in curl 7.9.1. Ancient. Historian vibes.


πŸ’… RETURN VALUE πŸ’…

curl_easy_setopt(3) returns a CURLcode indicating success or error.

  • CURLE_OK (0) means everything was OK ✨
  • non-zero means an error occurred β€” go peek at libcurl-errors(3) for the deets.

🫢 SEE ALSO 🫢


okay that's the whole page, bestie β€” go forth and negotiate your protocols πŸ’–βœ¨

This masterpiece brought to you by libcurl, dated 2026-10-12 β€” original page title CURLOPT_HTTP_VERSION(3), part of the Library Functions Manual. Mwah. πŸŽ€

πŸ“¦ where this page comes from