No.507


【Nginx】静的ファイルの転送が失敗するとき【Apache】

net::ERR_CONTENT_LENGTH_MISMATCHやNS_ERROR_NET_PARTIAL_TRANSFER地獄に嵌まった貴方へ

 WEBサーバーにファイルを置いてブラウザでアクセスする。こんな単純な行為が失敗して、全然解決できないことがある。
 ブラウザのインスペクタで確認すると下記のエラーが出ている場合が今回説明するハマリポイントだ。

ブラウザ エラー
Chrome net::ERR_CONTENT_LENGTH_MISMATCH
Firefox NS_ERROR_NET_PARTIAL_TRANSFER

 エラーメッセージだけで検索すると「nginxのキャッシュ設定」などいろいろ出てくる。それで解決できれば良し。

 だが、何をしても解決できない場合は下記を疑ってみよう。


確認すること

 以下のどれかに該当する場合はこの解決方法が有効だと思われる。

  • ファイルをネットワークドライブ(NFSやSambaなど)に設置していないか?
  • ファイルをdockerでbind mountしたディレクトリに設置していないか?
  • ファイルをvagrantのshared folderのディレクトリに置いていないか?

解決方法

 WEBサーバーの Sendfileディレクティブ で、カーネルのsendfileサポートを利用しないように設定しよう。

EnableSendfile directive apache
sendfile directive nginx

 apacheなら /etc/httpd/conf/httpd.conf などに下記を書こう。

EnableSendfile Off

 nginxなら /etc/nginx/nginx.conf などに下記となる。

sendfile off;

 apacheの方に sendfile を無効にした方がいいケースの説明がある。下記の部分が該当する。

ネットワークマウントされた DocumentRoot (例えば NFS や SMB) では、カーネルは自身のキャッシュを使ってネットワークからのファイルを 送ることができないことがあります。