Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I stumbled over a weird behavior when I try to send a post HTTP/2.0 request to apples push service:

        $http2ch = curl_init();
        curl_setopt($http2ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
        curl_setopt($http2ch, CURLOPT_URL, 'https://api.push.apple.com/3/device/megauniquedevicetokendummy');
        curl_setopt($http2ch, CURLOPT_PORT, 443);
        curl_setopt($http2ch, CURLOPT_HTTPHEADER, $httpHeader);
        curl_setopt($http2ch, CURLOPT_POST, true);
        curl_setopt($http2ch, CURLOPT_POSTFIELDS, $body);
        curl_setopt($http2ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($http2ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($http2ch, CURLOPT_HEADER, 1);
       $result = curl_exec($http2ch);
       if ($result === false) {
           throw new \Exception("Curl failed: " . curl_error($http2ch) . " | " . curl_getinfo($http2ch, CURLINFO_HTTP_CODE));

The exception is thrown with the Message: Curl failed: Received HTTP/0.9 when not allowed | 0

I explicitly told curl to use HTTP/2.0 on the second line of the code snipped above. Does anyone have any idea what that error message means and why curl uses such an old HTTP version?

I am on PHP 7.2 and curl version 7.66.0.

@PavelLint, yes I tried it both, also just not using the options leads to the same error. – rockZ Nov 26, 2019 at 11:28 Sounds like a potential bug, but I fail trying to reproduce that error using the curl command line against that URL... – Daniel Stenberg Nov 26, 2019 at 12:52 I think I probably found the issue. On the server where I send the request from, curl is compiled without "nghttp2". The server only accepts HTTP/2 connections which curl isn't capabl of when not compiled with "nghttp2". Using the --http2 flag curl responds with a curl: (1) Unsupported protocol. If I sent the very same request from my mac it works out of the box. – rockZ Nov 27, 2019 at 13:12 I just ran into the similar error like "Received HTTP/0.9 when not allowed" when git push to a repo on gitlab server. it succeeded when i retried though. – Richard Aug 25, 2022 at 3:42

This can also happen when the server is a grpc server. When curl is run against a grpc server or other non-HTTP server that doesn't respond with a valid HTTP status line that curl expects, curl will print the "Received HTTP/0.9 when not allowed".

It might be better if curl printed something like "unknown protocol" rather than assuming it is 0.9 because hitting something like a grpc server these days is going to be far more common than an actual HTTP 0.9 server.

@arahpanah I believe that if you are hitting a grpc endpoint but are expecting an ordinary web server it's possible there is a misunderstanding. The software you think is running isn't but something else is and curl is not the tool you need to access the server. For grpc, normally you need a custom client for that service (you'll need the protobuf file or discovery via reflection), but it's possible a tool like grpcurl might work. – d-chord Mar 5, 2022 at 18:23 I confirm that this message is also displayed by curl http://<server_ip:139> run against the Samba/SMB (Windows) servers. – mirekphd May 3, 2022 at 9:07 @arahpanah The solution is to use --http2-prior-knowledge which forces curl to use a HTTP2 only connection instead of an HTTP1.1 upgrade – Blackclaws Aug 23, 2022 at 11:55 I had this problem using python's http.server. The hint about it being possibly due to my response led me to reorder the send_response() / send_header() calls. I ended up finding that the send_response(200) needs to come first, then the send_header() calls, then the end_header(). To me send_response() and send_header() were just setting things in the object so it did not occur to me that the order between those two would make a difference. – Philippe Carphin Apr 1 at 1:40 Make sure that curl is compiled with nghttp2.

If you are unsure, you can check it on your terminal using curl --version

If you dont find nghttp2/{version} you need to compile curl again with nghttp2.

curl --version example where nghttp2 is missing:

curl 7.66.0 (amd64-portbld-freebsd12.0) libcurl/7.66.0 OpenSSL/1.1.1d zlib/1.2.11

curl --version example where nghttp2 is available:

curl 7.64.1 (x86_64-apple-darwin19.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.39.2
                I am suffering with the same issue. In my mac machine curl version 7.54, even i can't update version.
– hizbul25
                Apr 15, 2020 at 8:40
                @hizbul25 The version of curl isn't that important, you have to check if you version of curl is compiled with nghttp2
– rockZ
                Apr 15, 2020 at 11:35
                Found this answer after hours of searching. For anyone looking at how to compile curl with nghttp2, the instructions here worked for me: gist.github.com/jjpeleato/3327c2e38fc0fea7d6602401f9849809 If you already have a curl version installed, you'll need to point to the new one (/usr/local/bin/curl for me),
– Abhimanyu Talwar
                Apr 3, 2021 at 18:40
                Same here. My curl (7.79.1) has nghttp2/1.45.1 and gives the HTTP/0.9 error. I'm running the latest nghttpd web server for testing.
– Paul
                Feb 20, 2022 at 18:55

I do not believe it requires you to have a version of curl compiled differently, but rather set the option to allow http 0.9 as a response from your older server. PHP has some notes on "CURLOPT_HTTP09_ALLOWED" that may have differed when you posted your question via https://www.php.net/manual/en/function.curl-setopt.php

The option that overcame the error for me was:

curl_setopt($http2ch, CURLOPT_HTTP09_ALLOWED, true);
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.