Open
Description
What version of Go are you using (go version
)?
go version go1.8.3 darwin/amd64
What operating system and processor architecture are you using (go env
)?
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/tkng"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.8.3/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.8.3/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/z1/nc5xfnrs71g2zxr_chmshx3h0000gp/T/go-build993898931=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
What did you do?
Following snippet code should be enough to reproduce the problem.
https://play.golang.org/p/PmZWp6NJlq
If I disabled HTTP2 by the environment variable GODEBUG=http2client=0
, then I see no error. Hence I guess this issue is related to HTTP2. This is might be the same as #13959, but I'm not sure.
Also, I'm not sure this is the problem of golang's HTTP2 client library, or the problem of server side. (In most case, HTTP2 client works nicely.)
What did you expect to see?
I can connect to the server (by http2, or falling back to http1.1). At least, I want to see a more suggestive error message.
What did you see instead?
I saw an error message like following:
2017/07/11 15:22:01 http.Get failed, error: Get https://precious.jp: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Metadata
Metadata
Assignees
Type
Projects
Relationships
Development
No branches or pull requests
Activity
odeke-em commentedon Jul 11, 2017
@tkng could you please try with the latest Go and see what the result is? Perhaps the bug was fixed in Go1.9.
[-]Go's http client cannot connect to a HTTP2 server, returns Client.Timeout exceeded[/-][+]x/net/http2: connecting to some HTTP2 server returns Client.Timeout exceeded[/+]odeke-em commentedon Jul 11, 2017
I've made a bug repro at https://github.com/odeke-em/bugs/blob/master/golang/20979/main.go or
which when run seems like an infinite loop of renegotiating headers, until I hit Ctrl+C
/cc @tombergan @bradfitz
tkng commentedon Jul 11, 2017
@odeke-em thanks for your advice, I tried the latest golang master branch.
but, unfortunately, I still see the same error message as above.
bradfitz commentedon Jul 11, 2017
What software is
precious.jp
running? It's sending a GOAWAY to us in response to our first request:That looks busted on their side. If they didn't like something about our request, they sure didn't say why.
We write:
And then we read:
Maybe their implementation expects the SETTINGS ACK immediately after the initial SETTINGS frame (requiring a full RTT), instead of the the WINDOW_UPDATE + HEADERS in the middle? But the spec says in http://httpwg.org/specs/rfc7540.html#rfc.section.3.5:
So it does look like their server is at fault.
/cc @tombergan
bradfitz commentedon Jul 11, 2017
It works in Chrome, though.
What's the difference?
tkng commentedon Jul 12, 2017
@bradfitz thanks, your comment is helpful. Unfortunately, I don't know what kind of software is used. I'm just a developer of an image resizing proxy with Golang, and found that I can not access to the site through HTTP2 via Golang. I'll try to contact them, ask what software is used there.
But there's little hope to obtain detailed information. (I don't have a direct connection to an engineer.)
bradfitz commentedon Jul 12, 2017
@tatsuhiro-t, do you happen to have any idea here? Either of what software that site runs, or what their server might not like about Go's HTTP/2 client?
tatsuhiro-t commentedon Jul 12, 2017
It looks like the server does not like SETTINGS_MAX_HEADER_LIST_SIZE. It smells like a bug of the server side.
bradfitz commentedon Jul 12, 2017
@tatsuhiro-t, oh, indeed! Thanks.
It accepts a value up to 32KB, but one byte over that and it's rejected:
bradfitz commentedon Jul 12, 2017
The precious.jp server is probably misinterpreting the meaning of
SETTINGS_MAX_HEADER_LIST_SIZE
(http://httpwg.org/specs/rfc7540.html#SETTINGS_MAX_HEADER_LIST_SIZE) and thinking that it's how much the client will send, whereas it's actually the client telling the server how much the client is willing to receive. The server is probably confused and thinking, "No way, I'm not going to allocate more than 32KB for you!".We need to figure out which server this is and fix the interop problem.
tkng commentedon Jul 12, 2017
@tatsuhiro-t @bradfitz thanks for great progress.
Though I haven't receive any replying from
precious.jp
yet, I found that the specification of netty seems consistent with the current situation. According to the reference manual, there's a methodmaxHeaderListSize
inDefaultHttp2HeadersDecoder
class. If the value of parametermax
is greater than the value of parametergoAwayMax
, then a GO_AWAY frame will be generated.19 remaining items
HaraldNordgren commentedon Jul 26, 2018
I'm not sure this ticket is the correct place to post this. I found this ticket from #21301 which seemed like a better description of my situation, but it was closed as a duplicate so now I'm posting here.
I was interacting with a TLS host where
curl
works, but from Golang it was hanging on requests. Interestingly enough, for malformed requests the host would return quickly with an error. But for the data that turned out to be correct, it was timing out.I tried changing the HTTP version with no result. The solution that ended up working was to use
DynamicRecordSizingDisabled
in a config like thisAgain, Curl handles this seamlessly. So assuming there is a way to detect hosts that require
DynamicRecordSizingDisabled
, then it would be nice if Golang in the future could do this.bradfitz commentedon Jul 26, 2018
@HaraldNordgren, please file a separate crypto/tls bug for your case. It's unrelated to this. It sounds like a TLS issue instead of an HTTP issue.
keything commentedon Nov 14, 2018
hello, our client is as follows: `
timeout := time.Duration(999) * time.Millisecond
however, when we visit google with host maps.googleapis.com, timeout sometimes does not work。
The error we record is
net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
andnet/http: request canceled (Client.Timeout exceeded while awaiting headers)
.The latency is bigger than 100 second.
My question is that:
keything commentedon Nov 17, 2018
`tls.Config {
}`
it works. however, i don't know why it works.
when DynamicRecordSizingDisabled is true, we disables adaptive sizing of TLS records.
Does it depend on the implementation of tls in server side?
Gambler13 commentedon Jun 5, 2019
Any news on this issue? Because I encountered the same problem. I try to make a simple GET request. In the browser (Chrome), command line (cURL) and ozher tools like Postman the request is working fine. But if I try to do the request with the http.Client, nothing happens and the request will timeout.
GO env
Sample Programm code
Output
et/http: request canceled (Client.Timeout exceeded while awaiting headers)
Unfortunately, I can't provide the real URL (and in addition, a whitelisting is needed to call the url)
I already followed all the suggestions in this and other threads, but no one was working. And I also tried with golang 1.11.x, but ended with the same result.
Here the curl output (ignore the 404, this is intended)
https://hidden-url.cc:8084/rest2/SecUserMethods/method/Authenticate?Name=ss&Password=ss
Force TLS negotiation to only support HTTP/1.1