http.Client returning "http2: no cached connection was available"

1,151 views
Skip to first unread message

Russ Amos

unread,
Aug 2, 2016, 9:37:09 PM8/2/16
to golan...@googlegroups.com, Brad Fitzpatrick
I'm seeing "http2: no cached connection was available" failures from http.Client when I start many (~hundreds) requests at once. (This issue was also posted to golang-nuts@ in April, with no response)

I may not understand correctly, but I thought this kind of usage was fine with HTTP 1.1 and net/http, because the spec mandates a max number of outgoing connections to any given host, so http.Client throttles open connections and effectively queues requests past that. The http2 package seems not to do the same. That might be correct according to the spec (I don't know), but makes using http.Client weird -- I need to rate limit its usage if the server is HTTP 2, but it does rate limiting for me if the server is HTTP 1.1.

Is my understanding correct? Is this a bug? Is the expectation that my app should be rate limiting, regardless of server version? 

Also, It seems the error being returned is exported in the http2 package, but is not exported in the bundled version in net/http. If it was exported, I think I could at least retry on my own, but perhaps that's not the intended usage anyway.

I wrote this program hitting https://www.google.com/ to demonstrate -- here are a few run results:

$ GODEBUG=http2client=0 go run /tmp/foo.go
$ GODEBUG=http2client=0 go run /tmp/foo.go
$ GODEBUG=http2client=0 go run /tmp/foo.go
$ GODEBUG=http2client=0 go run /tmp/foo.go
$ GODEBUG=http2client=0 go run /tmp/foo.go

$ GODEBUG=http2client=1 go run /tmp/foo.go
Get https://www.google.com/: http2: no cached connection was available
Get https://www.google.com/: http2: no cached connection was available
Get https://www.google.com/: http2: no cached connection was available
...
$ GODEBUG=http2client=1 go run /tmp/foo.go
Get https://www.google.com/: http2: no cached connection was available
$ GODEBUG=http2client=1 go run /tmp/foo.go
$ GODEBUG=http2client=1 go run /tmp/foo.go
Get https://www.google.com/: http2: no cached connection was available
Get https://www.google.com/: http2: no cached connection was available
Get https://www.google.com/: http2: no cached connection was available
...
$ GODEBUG=http2client=1 go run /tmp/foo.go
Get https://www.google.com/: http2: no cached connection was available
Get https://www.google.com/: http2: no cached connection was available
Get https://www.google.com/: http2: no cached connection was available
...

Brad Fitzpatrick

unread,
Aug 2, 2016, 9:51:49 PM8/2/16
to Russ Amos, golang-nuts
Sorry, I don't read all of golang-nuts@ and never saw that. You could've escalated, though. There are at least two bug trackers available to you:


But I think your interpretation of the the HTTP/2 client is wrong.

If you're a video person, there's a talk on Go's HTTP client and its HTTP/2<->HTTP/1<->HTTP/2 dialing sandwich... 
If you're not a video person, the slides are linked from youtube.

Your output in this email from your program (https://play.golang.org/p/zKthX7Y9RW) doesn't include any error output. You can ignore the GODEBUG output. If it says there's no cached connection, that means http2 has no cached connection it needs to dial (which http1 will do). Then http1 works as normal, unless it decides that it negotiated http2, and then it goes back to http2.

But any rate-limiting you refer to is unchanged from before, since HTTP/1 still dials as normal. There's an open bug to optimize it (to only start 1 or 2 TCP connections until we know the negotiated protocol, and then settle on 6 or 1 max connections, etc), but it's no different today than Go 1.5 and earlier.

In any case, if you have a reproducible bug, let's move this to a bug tracker.












--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Russ Amos

unread,
Aug 2, 2016, 10:00:52 PM8/2/16
to Brad Fitzpatrick, golang-nuts
Those messages aren't GODEBUG output, it's the errors printed by the program as received from http.Client.Get. I'll file a bug.

Russ Amos

unread,
Aug 2, 2016, 10:08:08 PM8/2/16
to Brad Fitzpatrick, golang-nuts

Brad Fitzpatrick

unread,
Aug 2, 2016, 10:08:38 PM8/2/16
to Russ Amos, golang-nuts
Oh, sorry, I read that as GODEBUG=http2debug=1.

Okay, I'll follow up in https://golang.org/issues/16582

Russ Amos

unread,
Aug 2, 2016, 11:01:44 PM8/2/16
to Brad Fitzpatrick, golang-nuts
Thanks for the extremely quick triage, Brad. I'll work around it in my program, for now.

Ingo Oeser

unread,
Aug 3, 2016, 1:09:53 AM8/3/16
to golang-nuts
Could you document your workaround here?

It might be needed by others for the next 6 months because the bug has been classified as Go 1.8 work.

Reply all
Reply to author
Forward
0 new messages