Skip to content

x/net/http2: panic: interface conversion: http.http2Frame is *http.http2UnknownFrame, not *http.http2HeadersFrame #31986

@zhangriyueming

Description

@zhangriyueming

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

$ go version
go version go1.12.5 linux/amd64

Does this issue reproduce with the latest release?

yes

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

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build000458693=/tmp/go-build -gno-record-gcc-switches"

What did you do?

It is randomly occurred. Sometimes works fine without error, sometimes panics.

Maybe it associated with my Transport.

type Transport struct {
	upstream  http.RoundTripper
	jar       http.CookieJar
	delay     int
	userAgent string
}

func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
	resp, err := t.upstream.RoundTrip(r)
	if err != nil {
		return nil, err
	}

	if some_condition(resp) {
		
		req, err = http.NewRequest("GET", u.String(), nil)
		if err != nil {
			return nil, err
		}

		client := http.Client{
			Transport: t,
			Jar:       t.jar,
			CheckRedirect: func(req *http.Request, via []*http.Request) error {
				return http.ErrUseLastResponse
			},
		}

		resp, err = client.Do(req)
		if err != nil {
			return nil, err
		}

		redirectUrl := resp.Header.Get("Location")
		redirectLocation, err := url.Parse(redirectUrl)
		if err != nil {
			return nil, err
		}
		if redirectLocation.Host == "" {
			redirectUrl = fmt.Sprintf("%s://%s%s",
				resp.Request.URL.Scheme,
				resp.Request.URL.Host,
				redirectUrl)
		}
		
		req, err = http.NewRequest("GET", redirectUrl, nil)
		if err != nil {
			return nil, err
		}

		client = http.Client{
			Transport: t,
			Jar:       t.jar,
		}
		resp, err = client.Do(req)
		return resp, err
	}

	return resp, err
}

What did you expect to see?

Works without panics.

What did you see instead?

panic: 
api_1  | 15:58:21 app         | interface conversion: http.http2Frame is *http.http2UnknownFrame, not *http.http2HeadersFrame
api_1  | 15:58:21 app         | 
api_1  | 15:58:21 app         | 	
api_1  | 15:58:21 app         | panic: 
api_1  | 15:58:21 app         | err must be non-nil
api_1  | 15:58:21 app         | 
api_1  | 15:58:21 app         | 
api_1  | 15:58:21 app         | goroutine 
api_1  | 15:58:21 app         | 32
api_1  | 15:58:21 app         |  [
api_1  | 15:58:21 app         | running
api_1  | 15:58:21 app         | ]:
api_1  | 15:58:21 app         | panic
api_1  | 15:58:21 app         | (
api_1  | 15:58:21 app         | 0x9e0580
api_1  | 15:58:21 app         | , 
api_1  | 15:58:21 app         | 0xbb6070
api_1  | 15:58:21 app         | )
api_1  | 15:58:21 app         | 	
api_1  | 15:58:21 app         | /usr/local/go/src/runtime/panic.go
api_1  | 15:58:21 app         | :
api_1  | 15:58:21 app         | 565
api_1  | 15:58:21 app         |  +
api_1  | 15:58:21 app         | 0x2c5
api_1  | 15:58:21 app         |  fp=
api_1  | 15:58:21 app         | 0xc000407b68
api_1  | 15:58:21 app         |  sp=
api_1  | 15:58:21 app         | 0xc000407ad8
api_1  | 15:58:21 app         |  pc=
api_1  | 15:58:21 app         | 0x42bca5
api_1  | 15:58:21 app         | 
api_1  | 15:58:21 app         | net/http.(*http2pipe).closeWithError
api_1  | 15:58:21 app         | (
api_1  | 15:58:21 app         | 0xc0002d76a8
api_1  | 15:58:21 app         | , 
api_1  | 15:58:21 app         | 0xc0002d76f8
api_1  | 15:58:21 app         | , 
api_1  | 15:58:21 app         | 0x0, 0x0, 0x0)
api_1  | 	/usr/local/go/src/net/http/h2_bundle.go:3553 +0x1cd fp=0xc000407b90 sp=0xc000407b68 pc=0x67d70d
api_1  | 15:58:21 app         | net/http.(*http2pipe).CloseWithError
api_1  | 15:58:21 app         | (...)
api_1  | 	/usr/local/go/src/net/http/h2_bundle.go:3540
api_1  | net/http.(*http2clientConnReadLoop).cleanup(0xc000407fb8)
api_1  | 	/usr/local/go/src/net/http/h2_bundle.go:8084 +0x26c fp=0xc000407c90 sp=0xc000407b90 pc=0x694cac
api_1  | 15:58:21 app         | runtime.call32(0x0, 0xae22d8, 0xc00005a0b0, 0x800000008)
api_1  | 	/usr/local/go/src/runtime/asm_amd64.s:519 +0x3b fp=0xc000407cc0 sp=0xc000407c90 pc=0x45605b
api_1  | panic(0xa18c40, 0xc0005de240)
api_1  | 	/usr/local/go/src/runtime/panic.go:522 +0x1b5 fp=0xc000407d50 sp=0xc000407cc0 pc=0x42bb95
api_1  | 15:58:21 app         | runtime.panicdottypeE
api_1  | 15:58:21 app         | (...)
api_1  | 	/usr/local/go/src/runtime/iface.go:248
api_1  | runtime.panicdottypeI(0xbc7d40, 0xa6c9a0, 0xa20f80)
api_1  | 	/usr/local/go/src/runtime/iface.go:258 +0xf5 fp=0xc000407d78 sp=0xc000407d50 pc=0x409455
api_1  | net/http.(*http2Framer).ReadFrame(0xc00058f420, 0xc0002830e0, 0x0, 0x0, 0x0)
api_1  | 	/usr/local/go/src/net/http/h2_bundle.go:1759 +0x65d fp=0xc000407e38 sp=0xc000407d78 pc=0x67559d
api_1  | net/http.(*http2clientConnReadLoop).run(0xc000407fb8, 0xae22d8, 0xc0003b3fb8)
api_1  | 	/usr/local/go/src/net/http/h2_bundle.go:8102 +0x8f fp=0xc000407f70 sp=0xc000407e38 pc=0x694f7f
api_1  | net/http.(*http2ClientConn).readLoop(0xc00006b080)
api_1  | 	/usr/local/go/src/net/http/h2_bundle.go:8030 +0x76 fp=0xc000407fd8 sp=0xc000407f70 pc=0x694836
api_1  | runtime.goexit()
api_1  | 	/usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc000407fe0 sp=0xc000407fd8 pc=0x457bf1
api_1  | created by net/http.(*http2Transport).newClientConn
api_1  | 	/usr/local/go/src/net/http/h2_bundle.go:7093 +0x637

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions