Terminated HTTP/2 connections on macOS in Inea ISP
We’ve had a discussion about my issue on Reddit, but I wanted to try here too.
I have a symmetric 300 Mbps fiber connection at home and sometime in September/October 2021 I’ve started seeing weird network behavior. Google Chrome was first on my MacBook running the latest macOS when moving to a tab which was already opened but inactive for some time. If that tab contained i.e. GitHub, Reddit or StackOverflow then refreshing it took 10-30 seconds. After that refresh it worked fine and loaded quickly but after another inactivity it happened again. And again. And again. Other Chromium-based browsers acted the same (tested Safari, Brave and others).
After debugging Chrome, it turned out that some HTTP/2 requests get stalled and Chrome waits 10 seconds for each one to respond.
t=13679 [st=10002] HTTP2_STREAM_ERROR
--> description = "Abandoned."
--> net_error = "ERR_HTTP2_PING_FAILED"
--> stream_id = 129
t=13679 [st=10002] HTTP_TRANSACTION_RESTART_AFTER_ERROR
--> net_error = -352 (ERR_HTTP2_PING_FAILED)
So it looks like some HTTP/2 connections are terminated. One user from Reddit came out with a simple C keepalive test program which also replicates this issue. Here is my fork with additional arguments: https://gist.github.com/Najki/268cdf60ad6c9afcb4cb28c45f30d6e4
When run like that, it reads 0 bytes from server (issue replicated). This is one of Google’s IP addresses. Second argument is port. Third argument is the time for how long the command will wait before reading the response from server.
gcc keepalivetest.c -o /tmp/a.out && /tmp/a.out 172.217.16.46 80 80
Additional observations:
- It only happens when connected to my ISP (Inea). It works fine if I share a LTE connection from my iPhone or if I connect through a VPN.
- It only happens on macOS. Even running a Dockerized Linux machine on my macOS works fine → this one seems weird.
- I’ve contacted my ISP several times and the only workaround they’ve come up with is paying extra for a public IP address which bypasses their NAT or something.
What’s going on here? Is it macOS’a/Apple’s fault? Is it my ISP’s fault? Can I do anything about it?
Your ISP Support seems correct in that the problem is caused by a misbehavior of their NAT servers. They don't apparently know how to avoid this problem of their servers, so they advise you to avoid NAT entirely by using a static public IP.
Analysis: Chrome will send a PING frame before/after it has data to send to the server for a request. You can think of this as an alive test. This is also similar to just the sending of a stream of PING requests one after the other.
When this fails, it is because some network device (probably a NAT server) somewhere in the path between your browser and the server has decided to drop knowledge of your connection without sending an RST (Reset Connection) to both sides of the connection. In other words, the NAT translation table for your connection (IP translation) was lost.
Another possibility is that your request is served by two NAT servers of the ISP, where one doesn't know about the other, so your connections time out.
If my analysis is correct, you have the choices of either living with the problem, or keeping on pressuring your ISP Support to fix their technical problem, or to change ISP, or to demand a static public IP.