I have a Flask API hosted in Koyeb over the past 4 weeks. I have noticed that the API calls from the frontend site are intermittently getting stuck in the “pending” state and eventually returning a ERR_HTTP2_PROTOCOL_ERROR error. I also tried curling the API endpoint directly and seeing a similar behaviour. When running the Flask app locally, it works just fine. I have even deployed it into an AWS EC2 instance and it works fine.
Bear in mind that the issue is intermittent, if I refresh the page again and again, it can eventually fetch the response successfully.
The error from the browser looks as follows:
Running the API calls manually via Curl:
$ curl 'https://<host>.koyeb.app/<path>' -vvv
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 2606:4700:10::6816:4ebe:443...
* Connected to <host>.koyeb.app (2606:4700:10::6816:4ebe) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
* CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [19 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [2024 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [78 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
* subject: CN=*.koyeb.app
* start date: Sep 15 21:46:41 2024 GMT
* expire date: Dec 14 21:46:40 2024 GMT
* subjectAltName: host "<host>.koyeb.app" matched cert's "*.koyeb.app"
* issuer: C=US; O=Let's Encrypt; CN=E5
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* h2h3 [:method: GET]
* h2h3 [:path: <path>]
* h2h3 [:scheme: https]
* h2h3 [:authority: <host>.koyeb.app]
* h2h3 [user-agent: curl/7.83.0]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x26603890010)
} [5 bytes data]
> GET /<path> HTTP/2
> Host: <host>.koyeb.app
> user-agent: curl/7.83.0
> accept: */*
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [230 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [230 bytes data]
* old SSL session ID is stale, removing
{ [5 bytes data]
0 0 0 0 0 0 0 0 --:--:-- 0:01:40 --:--:-- 0< HTTP/2 200
< date: Mon, 16 Sep 2024 14:24:15 GMT
< content-type: application/json
< content-length: 21958
< access-control-allow-origin: http://<origin>
< access-control-expose-headers: Content-Type
< vary: Origin
< x-envoy-upstream-service-time: 735
< x-koyeb-backend: par1
< x-koyeb-glb: par1
< cf-cache-status: DYNAMIC
< server: cloudflare
< cf-ray: 8c4182697db85c06-SYD
< alt-svc: h3=":443"; ma=86400
<
{ [5 bytes data]
* HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)
0 21958 0 0 0 0 0 0 --:--:-- 0:01:41 --:--:-- 0
* Connection #0 to host <host>.koyeb.app left intact
curl: (92) HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)
I can see that the Koyeb host is proxied by Cloudflare from the http response headers above. I suspect that the issue might be related to Cloudflare, however there is no related configuration options available for the Koyeb users. I can see that there have been many forum discussions regarding the ERR_HTTP2_PROTOCOL_ERROR issue in the Cloudflare community forums, including this one: https://community.cloudflare.com/t/intermittent-and-random-failed-to-load-resource-net-err-quic-protocol-error/676273
I would appreciate if the Koyeb team looks into this, I have been finding the one-click Flask app deployments extremely valuable, however I have had to opt for an AWS deployment for the time being until we find a solution for this issue.