Curl error HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)

When I was working with one curl request module in my PHP project, I was not getting response in few request. Instead I got error response "Curl error HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)" This was happening 4-5 times out of 10 attempt.

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

if (curl_error($ch)) {
    $error_msg = curl_error($ch);
}

curl_close($ch);

print_r($error_msg);

After a few research I found the issue and solution. New curl version set default HTTP/2 option CURL_HTTP_VERSION_2TLS. On older curl versions, default option was CURL_HTTP_VERSION_1_1

So older APIs services don't appear to be compatible with the latest HTTP version. So request with HTTP/2 protocol will fail to connect API. This results in confusing behaviour because a script that works on one machine may not necessarily work on another. To maximise compatibility, you should specify CURLOPT_HTTP_VERSION for curl requests to older servers which don't support CURL_HTTP_VERSION_2TLS.

In my case, I was using PHP programming language, so adding following line to curl request solved the issue:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

If you get same error in other language, find way to switch HTTP version HTTP/2 to HTTP/1.1

I hope this small article find you helpful.

Tags: