クラウド時代のWebアプリケーション・スマートフォンアプリを開発・運用する会社です。 03-4577-8680 03-6673-4950

Golangでundefined: http2.Xxxxエラーが起きる場合の原因と対処

2017-02-10

google.golang.org/grpcを使用している場合に多いと思うのですが、glideで外部パッケージの依存性解決をしているはずなのに、go buildするとこのようなエラーが出ます。

vendor/google.golang.org/grpc/transport/handler_server.go:209: undefined: http2.TrailerPrefix
vendor/google.golang.org/grpc/transport/http2_client.go:890: undefined: http2.MetaHeadersFrame
vendor/google.golang.org/grpc/transport/http2_client.go:1012: undefined: http2.MetaHeadersFrame
vendor/google.golang.org/grpc/transport/http2_server.go:164: undefined: http2.MetaHeadersFrame
vendor/google.golang.org/grpc/transport/http2_server.go:325: undefined: http2.MetaHeadersFrame
vendor/google.golang.org/grpc/transport/http_util.go:382: f.fr.ReadMetaHeaders undefined (type *http2.Framer has no field or method ReadMetaHeaders)
vendor/google.golang.org/grpc/transport/http_util.go:512: f.fr.ErrorDetail undefined (type *http2.Framer has no field or method ErrorDetail)

結論から言ってしまうと、これはgolang.org/x/netのバージョン問題であります。
google.golang.org/grpcは、golang.org/x/netの最新版(後述の通り2016/01/31以降のバージョン)を想定しているのですが、どこかのパッケージがそれ以前のバージョンを要求しているので、glideが古い方(明確に指定されたバージョン)を取得しているわけです。

ではこれをどう対処するかですが、「いいから新しい方を使え!」という場合には指定方法があります。

まず、http2.TrailerPrefixが定義されたのがコミットID: d513e58596cd55e6f47cd1dcbff6b46035baeccb以降になります。
https://github.com/golang/net/commit/d513e58596cd55e6f47cd1dcbff6b46035baeccb
もしくはGo1.7向けのリリースブランチはここです。
https://github.com/golang/net/tree/release-branch.go1.7

ターットとなるコミットIDかリリースブランチ名を選んだら、glide.yamlに次のように追加します。

– package: golang.org/x/net
version: release-branch.go1.7
subpackages:
– context
– http2

versionには、コミットID・ブランチ名・リリースタグを指定することができます。

これでglide upを実行すると、golang.org/x/netのバージョンを指定していたパッケージがわかります。

[WARN] Conflict: golang.org/x/net rev is currently release-branch.go1.7, but github.com/gin-gonic/gin wants f315505cf3349909cdf013ea56690da34e96a451

なるほど。github.com/gin-gonic/ginがバージョンを指定していたのですね。

なおこの際、Warningは出ますが、パッケージの配置は完了しています。
設置されたバージョンは、golang/net/tree/release-branch.go1.7の最新コミットとなります。
(最新コミットを使って大丈夫なのか、という問題はもちろんありますが)

あらためてgo buildしてみると、エラー無くビルドが完了します。