Azure Reposのgit LFSへ大きいサイズのファイルのpushに失敗する

GitHubAzure Reposのgitレポジトリをよく利用します。その中でAzure Reposのgit LFSのpushで問題が発生しました。

Azure Reposのgit のpushに失敗するのです。

たまたま、ネットワークの調子が悪かっただけかと思い、別の日にもう一度pushしても失敗します。

エラーメッセージをよくみると、git LFSのpushに失敗しています。

そこで、git LFSだけのpushを手動で実行してみます。

C:\repos\repo1>git lfs push origin master
Uploading LFS objects: 60% (3/5), 83 MB | 7.8 MB/s, done.
LFS: Client error: https://user1@dev.azure.com/org1/proj1/_git/repo1/info/lfs/objects/518b55c856cdd90753bf192ae3aaae39f827f154b665a2531c338b7946f16b4b from HTTP 413
LFS: Client error: https://user1@dev.azure.com/org1/proj1/_git/repo1/info/lfs/objects/55efbc9d381d590e8e44d8e107191b89db2ad425b3b5121e14f706572792c345 from HTTP 413

二つののファイル対して、git lfs pushのHTTPのレスポンスステータスコードが413です。

レスポンスステータスコードが400番台なので、クライアントエラーです。

レスポンスステータスコード413のエラーの意味を調べてみます。

HTTP 413 Payload Too Large 「レスポンスステータスコード413は、リクエストエンティティがサーバーによって定義された制限よりも大きいことを示します」

アップロードのファイルサイズの問題のようです。

この二つのファイルのサイズを調べると、

159 MB (167,103,466 バイト)
199 MB (209,424,977 バイト)

でした。

Azure Reposの最大サイズ

LFSへ大きいサイズのファイルの失敗しているので、まずは、Azure Repos (git)の仕様上のサイズ制限を確認します。

Azure Repos (git)の最大サイズの仕様はマイクロソフトのサイトにありました。2022年7月時点の情報を抜粋すると以下の通りです。

  • gitレポジトリの最大サイズ: 250GB (LFSの分はこのサイズに含まれない。推奨最大サイズは10GB)
  • 1回のpushの最大サイズ: 5GB
  • LFSのオブジェクトのサイズ: オブジェクト(BLOB)のサイズ、1回のpushのサイズともに制限はない

今回の問題になっているLFSオブジェクトのサイズは200MB程度です。Azure Repos (git)の仕様上の制限でエラーになっているわけではありません。

類似問題を探す

類似問題が発生していないかを確認します。Visual StudioのDeveloper Communityに情報がありました。

2019/12/19 Can’t push large GIT LFS files to repository from pipeline on Microsoft Hosted agent.

ローカルPC上ではなくAzure Pipelinesで発生した現象ですが、git pushで発生した問題です。私が遭遇したエラーメッセージと同じです。

LFS: Client error: https://.../info/lfs/objects/7a6a96d06879e9f4f4d9b07a10a25baf515ad0843b9deb6b07975e15b86c2ed4 from HTTP 413 
error: failed to push some refs to 'https://....'

ファイルサイスが128MB以上のときに問題が発生するとのこと。

この報告の中で原因と対策に関する記載は以下の通りです。

Aug 18, 2020 Danny McCormick [MSFT]

We have a fix for this in Azure Pipelines rolling out soon. The fix forces git to use HTTP/1.1 in pipelines that have a checkout step. This change will not affect calls made from outside of pipelines. For those, the recommendation is still setting up your git config to use HTTP/1.1 by running “git config http.version HTTP/1.1”.

The underlying issue here is that Git changed their default protocol from HTTP/1.1 to HTTP/2. Unfortunately, IIS (which Azure DevOps sits behind) has security measures that prevents the type of large content-length headers that HTTP/2 + LFS leads to (IIS also has some other challenges with HTTP/2). Since we can’t change LFS, and can’t up that limit without exposing some security risks, this solution takes us as far as we can go without introducing new issues.

日本語訳は以下の通りです。

2020年8月18日 Danny McCormick [マイクロソフト]

Azure Pipelinesでは、この問題を解決するための修正を近日中に公開する予定です。この修正により、チェックアウトステップがあるパイプラインでは、gitはHTTP/1.1を使用するように強制されます。この変更は、パイプラインの外から行われた呼び出しには影響しません。そのような場合は、"git config http.version HTTP/1.1" を実行して HTTP/1.1 を使用するように git config を設定することが推奨されます。

この問題の根本は、Git がデフォルトのプロトコルを HTTP/1.1 から HTTP/2 に変更したことです。残念ながら、IIS(Azure DevOpsの背後に位置する)は、HTTP/2 + LFSがもたらす大きなコンテンツ長ヘッダーの種類を防ぐセキュリティ対策をしています(IISには、HTTP/2に関する他の課題もあります)。私たちはLFSを変更することができず、いくつかのセキュリティリスクをさらすことなくその上限を上げることができないので、この解決策は、新たな問題を引き起こすことなく、私たちができる限りのことをやってのけるのです。

git LFSの変更履歴を確認するとv2.9.0 (2019/10/18) でHTTP/2 がサポートされ、既定でHTTP/2 が使われるようになったようです。

Azure Repos (git)は、HTTP/2での通信のときにサーバー側でのセキュリティ対策の影響で、大きなサイズのアップロードに失敗する問題を持っているようです。

この問題は、通信プロトコルにHTTP/1.1を使うときは発生しないとのこと。

そのためgitがHTTP接続に使うプロトコルをHTTP/2の代わりにHTTP/1.1にすると問題が発生しなくなります。

Azure Repos (git)でHTTP 413が発生するときの対策

Azure Repos (git)でHTTP 413エラーが発生するときは、「HTTP接続の使うプロトコルを既定値のHTTP/2からHTTP/1.1に変更する」ことが対策です。

コマンドラインによるプロトコルの設定は以下の通り

git config http.version HTTP/1.1

この設定は、PCのグローバル(–global)に設定するのではなく、問題が発生するレポジトリごとに設定するのがよいと思います。なぜなら、問題が発生しないレポジトリでは、既定値のHTTP/2のままの方がいろいろな面で効率が良いからです。


今回の投稿では、Azure Repos (git)へのpushで、HTTP 413が発生するときの対策についての説明でした。

コメントを残す