Code change:
t.Errorf("expect response HTTP header Connection to be empty, but got: %s", v) } } <ins> // TestGOAWAYConcurrency tests GOAWAY frame will not affect concurrency requests in a single http client instance. // Known issues in history: https://github.com/kubernetes/kubernetes/issues/91131. func TestGOAWAYConcurrency(t *testing.T) { s, err := newTestGOAWAYServer() if err != nil { t.Fatalf("failed to set-up test GOAWAY http server, err: %v", err) } s.StartTLS() defer s.Close() client, err := newGOAWAYClient(nil) if err != nil { t.Fatalf("failed to set-up client, err: %v", err) } const ( requestCount = 300 workers      = 10 ) expectWatchers := 0 urlsForTest := []string{urlGet, urlPost, urlWatch, urlGetWithGoaway, urlPostWithGoaway, urlWatchWithGoaway} urls := make(chan string, requestCount) for i := 0; i < requestCount; i++ { index := rand.Intn(len(urlsForTest)) url := urlsForTest[index] if url == urlWatch || url == urlWatchWithGoaway { expectWatchers++ } urls <- url } close(urls) wg := &sync.WaitGroup{} wg.Add(workers) watchers := make(chan (<-chan watchResponse), expectWatchers) for i := 0; i < workers; i++ { go func() { defer wg.Done() for { url, ok := <-urls if !ok { return } w, err := requestGOAWAYServer(client, s.URL, url) if err != nil { t.Errorf("failed to request %q, err: %v", url, err) } if w != nil { watchers <- w } } }() } wg.Wait() // check if watch request is broken by GOAWAY frame watchTimeout := time.NewTimer(time.Second * 10) defer watchTimeout.Stop() for i := 0; i < expectWatchers; i++ { var watcher <-chan watchResponse select { case watcher = <-watchers: default: t.Fatalf("expect watcher count: %d, but got: %d", expectWatchers, i) } select { case watchResp := <-watcher: if watchResp.err != nil { t.Fatalf("watch response got an unexepct error: %v", watchResp.err) } if !reflect.DeepEqual(responseBody, watchResp.body) { t.Fatalf("in-flight watch was broken by GOAWAY frame, expect response body: %s, got: %s", responseBody, watchResp.body) } case <-watchTimeout.C: t.Error("watch receive timeout") } } } </ins>

Related discussion:
text: What happened: We enabled feature in our large-scale cluster, and we found client(Kubelet) may got error(500 http code response) like after received GOAWAY frame. I had already re-produce this bug and open an in golang repo. So far I think this bug only occur with a small probability when client request server in high concurrency use a same httpclient instance, and it's a golang sdk bug in http client. Before I solved this issue, I suggest do NOT enable GOAWAY() feature. As it's a golang sdk bug(currently I known and doubt) in http client, revert GOAWAY feature(codes) is not necessary.
cc
/sig api-machinery
Thanks for the report.
Based on not setting the field, I think it defaults that way, so that's good. We will leave the option and filter so that when golang updates its client, we will have a simple way to turn it on and execute it.
Sure. I am trying to fix the golang http client issue and will update progress at . After golang http client issue fixed, I will add more concurrent test cases to see if there are any other bugs may occur by GOAWAY feature. BTW, we still enable GOAWAY feature in our production cluster, because there is no any evidence told us this error will influence SLO, as all most components(kubelet, controller-manager, scheduler) is controller work mode and will re-try after got error. /assign
Golang version or required, which will release at 07/01/2020.
Kubernetes v1.19(or master branch) now is using golang 1.15, and golang 1.15 has fixed the issue. And is on going. Let me add more test cases to ensure the error will not happen again.
I think we should re-open this issue because of . /re-open