Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting "curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)"

I have a Django app which returns a large JSON while calling an API. The problem is when I'm requesting the data, the data itself is truncated which is crashing the frontend.

I'm using cloud front for DNS and SSL and other feature provided by them for caching and improved performance.

I tried curling the API and got the following error from curl:

curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)

I tried disabling the Cloudflare but didn't work. On my localhost, however, everything works fine.

HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)

  • Closing connection 0
  • TLSv1.2 (OUT), TLS alert, Client hello (1): curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)

The JSON should be fetched entirely without getting chunked.

like image 626
Devopsception Avatar asked Jun 02 '19 08:06

Devopsception


4 Answers

I got the same error with an application behind an AWS Application Load Balancer, using command:

curl "https://console.aws.example/api/xxx" -b "SESSION=$SESSION"
                                                                         

15:14:30 curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)

I had to force the use of HTTP/1.1 with the argument --http1.1

So the final command is:

curl "https://console.aws.example/api/xxx" -b "SESSION=$SESSION" --http1.1
like image 104
veben Avatar answered Oct 13 '22 00:10

veben


I had this issue with AWS's Application Load Balancer (ALB). The problem was that I had Apache configured to use http2, but behind an ALB. The ALB supports http2 by default:

Application Load Balancers provide native support for HTTP/2 with HTTPS listeners. You can send up to 128 requests in parallel using one HTTP/2 connection. The load balancer converts these to individual HTTP/1.1 requests and distributes them across the healthy targets in the target group. Because HTTP/2 uses front-end connections more efficiently, you might notice fewer connections between clients and the load balancer. You can’t use the server-push feature of HTTP/2. 1

So, curl was using HTTP/2 to connect with the ALB, which was then converting it into an HTTP/1 request. Apache was adding headers to the response asking the client to Upgrade to HTTP/2, which the ALB just passed back to the client, and curl read it as invalid since it was already using an HTTP/2 connection. I solved the problem by disabling HTTP/2 on my Apache instance. Since it will always be behind an ALB, and the ALB is never going to make use of HTTP/2, then there is no point of having it.

like image 34
lightswitch05 Avatar answered Oct 13 '22 00:10

lightswitch05


With Nginx, you can experience this error in curl by having two http2 virtual hosts listening on the same server name. Running a check on your nginx config file will throw a warning letting you know that something isn't right. Fixing/removing the duplicate listing fixes this problem.

# nginx -t
nginx: [warn] conflicting server name "example.com" on 0.0.0.0:443, ignored
nginx: [warn] conflicting server name "example.com" on [::]:443, ignored
like image 22
jaywilliams Avatar answered Oct 13 '22 00:10

jaywilliams


Fix or Remove the Content-Length header in your HTTP request.

I was trying to connect to an AWS Gateway when this issue occurred to me. I was able to get the correct response using POSTMAN but if I copied over the same headers to curl, it would give me this error.

What finally worked for me was removing the Content-Length header as the length of the request in curl wasn't matching the same as it was in POSTMAN.

Since in my case I was only testing the API so this is fine, but I wouldn't suggest removing this header in production. Check to make sure the length is calculated correctly if this is occurring to you in a codebase.

like image 20
Chirag Bhatia - chirag64 Avatar answered Oct 12 '22 23:10

Chirag Bhatia - chirag64