-
Notifications
You must be signed in to change notification settings - Fork 18k
x/net/http2: downloading files from kernel.org results in PROTOCOL_ERROR stream error #19035
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Here’s the result of running with |
Thanks for the report. So, the trace says that kernel.org is sending us the PROTOCOL_ERROR:
But I see nothing obviously wrong. I imagine its accounting of flow control differs from ours and it's complaining about that. The response says they're using nginx. Unfortunately, I'm unable to reproduce using your program. Oh, except the machine I'm running it on doesn't have IPv6, if that's relevant. (Your example connected via IPv6) /cc @tombergan |
Thanks for the quick reply. IPv6 does not seem to be relevant: debug.gz is another trace of the same problem after deleting my IPv6 address and default route. I can reproduce the issue on my Google workstation. I’ve granted you login permission to it, see the email I sent you on your corp account. Hope that helps. Note that all computers from which I can reproduce this are located in Zürich, Switzerland, whereas all kernel.org mirrors (as per traceroute) are located in the US, i.e. ≥ 100ms of latency away. |
I can repro the problem. @stapelberg's example downloaded 155400 bytes before failing and my repro downloaded 85768 bytes before failing, so the failure appears to be nondeterministic. Go's WINDOW_UPDATEs look correct to me, in both traces. There is consistently a 1 minute gap between Go sending the last WINDOW_UPDATE and receiving the RST_STREAM(PROTOCOL_ERROR). My ping time to the server is only 5ms. This suggests we're hitting a timeout, possibly due to flow control not being properly updated as @bradfitz suggested. We might be hitting this code in nginx. I do not see any WINDOW_UPDATEs on the stream, only on the connection. But Go sends a connection-level WINDOW_UPDATE with incr=1GB at startup, so nginx should not be blocked on connection-level flow control tokens. I suspect a bug in nginx, since everything looks ok on Go's end, but I cannot be sure. @VBart, any ideas? /cc @VBart |
Ping @VBart. |
The exact reason of RST_STREAM should be in error log. But yes, this looks like a request timeout (see the send_timeout directive), which is 1 minute by default. While from Go logs you see that WINDOW_UPDATE was sent to nginx, I suspect nginx didn't receive it and closed stream after a minute of waiting. That can be a network problem, e.g. some intermediate buffering. Enabling debug log in nginx will show the truth. |
It would be helpful if somebody could put together a standalone repro for this, ideally in a Docker container with both nginx and Go, along with any necessary network delaying (e.g. http://bencane.com/2012/07/16/tc-adding-simulated-network-latency-to-your-linux-server/), which probably doesn't run in a container. But it also seems like an nginx bug to me. @VBart says:
But Go only speaks HTTP/2 over TLS, so almost certainly not any intermediate buffering. In any case, a repro that doesn't involve kernel.org so we can enable nginx debug logs and modify nginx source code at will would be super helpful. |
I'm back from leave. Can somebody try and reproduce this and see if it's still happening, ideally with Go tip? Maybe something in Go or something in nginx changed. |
Cannot reproduce this anymore with go +21672b36eb:
|
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?go version go1.8rc3 linux/amd64
(also reproducible usinggo version go1.7.1 linux/amd64
)What operating system and processor architecture are you using (
go env
)?What did you do?
https://play.golang.org/p/KUK5nfKxgu
What did you expect to see?
The program should terminate without an error.
What did you see instead?
(map reformatted for readability)
I think this is an
x/net/http2
related error, because running the program with the environment variableGODEBUG=http2client=0
works as expected.Other HTTP2 clients, such as
curl --http2 -O https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.9.9.tar.xz
, work as expected.The text was updated successfully, but these errors were encountered: