-
Notifications
You must be signed in to change notification settings - Fork 17.6k
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
x/net/http2: RST_STREAM ErrCode=CANCEL sent to a closed stream #41570
Comments
cc @fraenkel |
/cc @tombergan |
So I won't comment on the setup but its not exactly trivial and the above well, wasn't enough. What I ended up seeing were 2 types of reasons for the RST_STREAM:
|
@fraenkel Could I provide you more debug information that will help you say why the CANCEL is being send ? Here
I see all required data: the stream id, the END_STREAM flag and the body/data. But for some reason Golang net::Transport marks it as insufficient/incorrect and sends back the RST_STREAM+CANCEL. |
I told you why. I added debug to see why cancel was sent. I can give you the line numbers. Again, the client is cancelling the context or the response body is closed before we finishing reading the body. |
Sorry, I am not so familiar with Golang net internals and I didn't (I still don't) understand whether the problem is in the client (Golang) or in the server (Tomcat). |
@martin-g could you cc the Vegeta folks on this, since their client is apparently the cause? |
@martin-g: It's possible your requests are timing out, since you're sending at max rate. There's a default timeout of 30s. Do you see the same thing when you set |
The default timeout is 30s but the load test runs for just 5s. I think this excludes this possibility. But I will test it anyway! |
Confirmed! Same behavior with |
This same issue (RST_STREAM + CANCEL sent by HTTP2 client to server after reading the DATA frame of a response) was reported with regard to exchange between restic backup and rclone utility: rclone/rclone#2598 The root cause in that case was that restic (client) read exactly the number of response bytes it requested but did not wait for stream EOF. Not waiting for EOF after reading full response body never posed a problem with HTTP/1.1 but results in sporadic RST_STREAM issues with HTTP/2. @fraenkel The issue was investigated here: https://github.com/ivandeex/rclone/tree/stream-reset/stream-reset#premature-stream-reset-between-restic-and-rclone
runs successfully
prints error messages
is successful again. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes!
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I am load testing Apache Tomcat web server with Vegeta
Together with Tomcat's developers we have found that Golang sends RST_STREAM + CANCEL after reading the DATA frame of a response.
Initially I thought it is a problem in Vegeta (issue) but after some investigation I've
found #27208 and its fix.
I've exported
GODEBUG="http2debug=2"
and re-run Vegeta. It doesn't fail always but just for some HTTP2 streams. The debug information for a problematic stream looks like:What did you expect to see?
I expect to see error message explaining what kind of problem there is with the DATA frame.
I do not expect Golang HTTP2 library to send more frames to a closed stream. The server sends DATA with END_STREAM then Golang http2 fails for some reason and tries to send new frames to the server
What did you see instead?
I see Golang trying to send new frames to a closed stream and errors in the server logs explaining that the client is trying to use a closed stream.
Steps to Reproduce
I guess the following steps won't be very friendly to a Golang developer (or any non-Java developer) but I wasn't able to find a way to make it smaller.
There is a lenghtly discussion at https://lists.apache.org/thread.html/r6f9ce1521346d5ced72c82a4b5d882a624514c9a7b308ad54f064ba1%40%3Cusers.tomcat.apache.org%3E where I explained that I have tried with other HTTP2 servers (Golang, Rust, Node.js and Netty) - there is no such issue with them!
So I guess Tomcat produces problematic DATA frames in some cases.
I'd be very grateful if someone helps me to find out what exactly causes Golang net library to decide to send the RST_STREAM + CANCEL frame, for example by adding more debug statements to
http2debug=2
.Steps:
The text was updated successfully, but these errors were encountered: