Skip to content

net/http2: Transport received Server's graceful shutdown GOAWAY] after Request.Body was written; define Request.GetBody to avoid this error #62453

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

Closed
AtlanCI opened this issue Sep 5, 2023 · 12 comments
Labels
FrozenDueToAge help wanted WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@AtlanCI
Copy link

AtlanCI commented Sep 5, 2023

What version of Go are you using (go version)?

$ go version
go 1.20.3 amd64

Does this issue reproduce with the latest release?

This problem is a bit strange, I can't reproduce it The latest version and the version I am currently using.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
It runs in my production environment without any special env

What did you do?

Program Logic

I am writing a storage platform service that accepts HTTP POST requests from users and uploads files through Forms I need to send this Form form to the S3 backend. During this process, I will not read the HTTP Body passed by the user, which is the r.body below, and pass it directly to S3 to achieve pseudo streaming upload Because S3 has some special authentication and other information, I use io. MultiReader() in the following code to add my information to the body and upload it to S3.

I am building a request to initiate a request to the S3 service Please note that I used io.MultiReader() in the sample code I provided. Please ignore it. When I called http.do(req), it returned http2: Transport: cannot retry err [http2: Transport received Server's Graceful shutdown GOAWAY] after Request. Body was written; Define Request. GetBody to avoid this error How should I fix such an error.

My HTTP client configuration

       dialer = &net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
	}
	_s3HTTP = &http.Client{Transport: &http.Transport{
		Proxy:                 http.ProxyFromEnvironment,
		DialContext:           dialer.DialContext,
		ForceAttemptHTTP2:     true,
		MaxIdleConns:          1000,
		IdleConnTimeout:       90 * time.Second,
		TLSHandshakeTimeout:   20 * time.Second,
		ExpectContinueTimeout: 5 * time.Second,
		MaxIdleConnsPerHost:   500,
	}}
   
	// make req
	postUrl := c.url()
	request, err := http.NewRequestWithContext(ctx, http.MethodPost, postUrl, io.MultiReader(bytes.NewReader(b.Bytes()[:fieldLen]), bytes.NewReader(fileNameBuffer.Bytes()[:nameLen]), r.Body))

	if err != nil {
		return nil, fmt.Errorf("http.NewRequestWithContext: %w", err)
	}

	resp, err := c.h.Do(request)
	if err != nil {
                // this is error
		return nil, fmt.Errorf("h.Do(): %w", err)
	}

What did you expect to see?

It should upload files to a service similar to S3 normally. How should I fix this error?

What did you see instead?

It prompts the following error message.

h.Do(): Post "https://eos-xxx.cmecloud.cn/s3-bucket": http2: Transport: cannot retry err [http2: Transport received Server's graceful shutdown GOAWAY] after Request.Body was written; define Request.GetBody to avoid this error

@panjf2000
Copy link
Member

Related issue: #62450

@AtlanCI
Copy link
Author

AtlanCI commented Sep 5, 2023

Related issue: #62450

I cannot change the body Because it requires pseudo streaming Is there any other way? For example, http.client

@panjf2000
Copy link
Member

You can avoid this by assigning a valid function of func() (io.ReadCloser, error) to request.GetBody, just like the error said.

@AtlanCI
Copy link
Author

AtlanCI commented Sep 5, 2023

You can avoid this by assigning a valid function of func() (io.ReadCloser, error) to request.GetBody, just like the error said.

I understand that req. GetBody needs to meet the requirement of repeated reading, but my body cannot be repeated.

@panjf2000
Copy link
Member

panjf2000 commented Sep 5, 2023

You can avoid this by assigning a valid function of func() (io.ReadCloser, error) to request.GetBody, just like the error said.

I understand that req. GetBody needs to meet the requirement of repeated reading, but my body cannot be repeated.

It can get tricky if you can't replay your r.Body, the root cause of this issue seems to be a server-side (S3) problem, maybe you should seek help from the AWS team, to find out what's happening over there.

@AtlanCI
Copy link
Author

AtlanCI commented Sep 5, 2023

You can avoid this by assigning a valid function of func() (io.ReadCloser, error) to request.GetBody, just like the error said.

I understand that req. GetBody needs to meet the requirement of repeated reading, but my body cannot be repeated.

It can get tricky if you can't replay your r.Body, the root cause of this issue seems to be a server-side (S3) problem, maybe you should seek help from the AWS team, to find out what's happening over there.

Can I change ForceAttemptHTTP2: true, to false?

@panjf2000
Copy link
Member

You can avoid this by assigning a valid function of func() (io.ReadCloser, error) to request.GetBody, just like the error said.

I understand that req. GetBody needs to meet the requirement of repeated reading, but my body cannot be repeated.

It can get tricky if you can't replay your r.Body, the root cause of this issue seems to be a server-side (S3) problem, maybe you should seek help from the AWS team, to find out what's happening over there.

Can I change ForceAttemptHTTP2: true, to false?

I fail to see how this is going to help

@AtlanCI
Copy link
Author

AtlanCI commented Sep 5, 2023 via email

@panjf2000
Copy link
Member

Sorry, I misunderstood this configuration Is there no other way to do it?

I'm afraid there is nothing Go can do about this issue, but I'll leave this issue on and see if anyone else has a viable solution.

@AtlanCI
Copy link
Author

AtlanCI commented Sep 5, 2023 via email

@cherrymui
Copy link
Member

This looks like a question about how to use Go http on S3 pseudo streaming. If you ask on a forum rather than on the issue tracker, more people will see your question, and you will get better answers. See https://golang.org/wiki/Questions . Thanks.

@cherrymui cherrymui added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Sep 7, 2023
@gopherbot
Copy link
Contributor

Timed out in state WaitingForInfo. Closing.

(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

5 participants
@panjf2000 @gopherbot @cherrymui @AtlanCI and others