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


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してみると、エラー無くビルドが完了します。

最新記事

すべて表示

SQLite(sqlite3)で “no such table”

小ネタです。 SQLiteを使っていて "no such table" とエラーが出た場合、 DBファイル名の指定が空になっている、という凡ミスを起こしていないかを確認してみましょう。 ・・・ そういう凡ミスをしてしばし悩んだので… ファイル名の指定が空になっている場合、一時的なインメモリDBとして保存されます(※1)。 つまりDB接続を切断すると中身は消えます。 なので接続

アプリケーションサーバにポートを指定せずに起動すると?

最近、 Goで書かれたアプリケーションサーバが起動しない! ->原因: .env ファイルが欠けていた というドタバタがありました。 結局Goと関係ないですが、この時、 「あまりGoに慣れてないのでGoの問題かと…」「DockerまだよくわかってなくてDockerの問題かと…」 というような声があったのて、あえてGoで検証してみようと思ったわけです。 さて、Goでサーバサイドのシステムを作

GitLab 9.1.2 (MySQL) を 11.4.0 (PostgreSQL) にアップグレード

弊社ではかなり前からGitLab(CE)を自社環境で運用しているのですが、ふと気付くと、バージョンがだいぶ先に行ってしまっていました。 とくに最近のバージョンでは Auto DevOps なども使えるようになっていたりするので、さすがにそろそろキャッチアップしたいと考えたわけです。 現行の環境は次の通りです: GitLab 9.1.2 sameersbn/gitlab 使用 MySQL 5.6