0

When I'm doing a CURL call curl https://example.com from a docker container, I got the error curl: (92) HTTP/2 stream 0 was not closed cleanly: HTTP_1_1_REQUIRED (err 13). But when I'm running the same command from the host server (RHEL) where docker container is running, it is working fine.

So, I have added --http1.1 to the command in docker container, then it is working fine. But when I run the same command with --http1.1 on host server, then I got error curl: option --http1.1: is unknown.

  1. How the curl picks up the http version while making the call? Is there any setting that we can define to use a specific version by default?
  2. Why --http1.1 is not working on server, but working in docker container?

Curl version on server is 7.29.0. Curl version on docker container is 7.64.0

1 Answer 1

0

TL;DR: Fix your webserver.

Long story

Your HTTP server must be doing something "wrong"! curl will not attempt to do a HTTP/2 connection unless the server advises that it can do it.

So, the answer to the questions are:

How the curl picks up the http version while making the call?

It listens to what the server claims to support.

Is there any setting that we can define to use a specific version by default?

Yes, that's built in to the HTTP protocol (first line of response); actually, considering you're using TLS (https://…), this should already be clearly defined by client using the h2 protocol identifier in TLS/ALPN, and the server will respond that it supports the h2 protocol, i.e. it agrees that it can indeed talk HTTP/2.

Otherwise, curl will not use HTTP/2.

You can check your HTTP server's misbehaviour yourself!

$ # https://stackoverflow.com does support HTTP/2
$ curl --verbose --output /dev/null https://stackoverflow.com
…
* Connected to stackexchange.com (151.101.65.69) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
…
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN: server accepted h2
…
* Using HTTP2, server supports multiplexing
…
> GET / HTTP/2

So, here you can see, curl offers h2 as protocol ID to the server, and the server actually has to accept that before curl uses HTTP/2.

Compare that with what an outdated webserver does, and how curl reacts:

$ # https://www.gnu.org only supports HTTP/1.1, in 2023.
$ curl --verbose --output /dev/null https://www.gnu.org/software/grub/manual/grub/html_node/normal.html
* Connected to www.gnu.org (2001:470:142:5::116) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
…
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted http/1.1
…
> GET /software/grub/manual/grub/html_node/normal.html HTTP/1.1

So, your web server must be telling curl in the TLS connection establishment that it supports HTTP/2 (by signalling h2 support), but then actually not support it.

Why --http1.1 is not working on server, but working in docker container?

Your host server's curl is very old; that option was added in curl version 7.33.0, which was nearly 10 years ago.

2
  • Thanks for the response. The server is accepting the h2 and curl is selecting h2 as you mentioned. Is this a docker image issue? Or server issue? If this is a docker issue, how can we fix this? I see below log when I ran curl -Iv <url>. Connection state changed (MAX_CONCURRENT_STREAMS == 100)! HTTP/2 stream 0 was not closed cleanly: HTTP_1_1_REQUIRED (err 13)
    – noonenine
    May 30 at 2:58
  • Server issue, as said in the first line. May 30 at 6:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .