できない.dev

nginx「413 Request Entity Too Large」の原因と直し方

413 Request Entity Too Large は、client_max_body_size を送るサイズより大きくして reload すれば直る。
既定の上限は 1m で、超えた本文は転送先へ届く前に nginx が拒否する。

公開: 更新:

要約

413 Request Entity Too Large は、リクエストの本文が client_max_body_size を超えたときに nginx が返す。
既定の上限は 1m なので、1MB を超えるファイルのアップロードは設定を書くまで通らない。上限を送るサイズより大きくして reload すれば直る。

本文は転送先へ届かないので、アプリのログには何も残らない。
nginx の error.log には、送ろうとしたサイズが出る。

[error] 49#49: *5 client intended to send too large body: 2097152 bytes, client: 127.0.0.1, server: , request: "POST /up/ HTTP/1.1", host: "127.0.0.1"

Transfer-Encoding: chunked で送った場合は、client intended to send too large chunked body: 1048384+65524 bytes のように出る。
公式ドキュメントによると、ブラウザはこのエラーを正しく表示できない。
アップロードが通信エラーで失敗して見えるときも、このログを確かめる。

応答の本文の末尾に nginx/1.27.5 のような署名が出ていれば、その 413 は nginx が返している。

解決策

1. client_max_body_size を書く

http・server・location のどこにでも書ける。
アップロードの経路だけ上限を上げるなら、location に書く。

server {
    listen 80;
    client_max_body_size 20m;
 
    location /upload/ {
        client_max_body_size 100m;
        proxy_pass http://app:3000;
    }
}

0 を指定すると、サイズの検査そのものが無効になる。
公開サーバーでは、大きな本文を無制限に受け付けることになる。

2. 実際に効いている値を探す

nginx -T は、読み込まれたすべての設定ファイルを連結して表示する。conf.d の別のファイルにある指定も、これで見つかる。

nginx -T 2>/dev/null | grep -n client_max_body_size

3. 検査してから reload する

nginx -t && nginx -s reload

反映されたかどうかは、上限に近いサイズのファイルを送って確かめる。

dd if=/dev/zero of=big.bin bs=1M count=5
curl -s -o /dev/null -w '%{http_code}\n' -X POST --data-binary @big.bin http://localhost/upload/

4. 経路上のすべての nginx で上げる

nginx を 2 段に重ねているときは、どちらの error.log に client intended to send too large body が出ているかで、止めている側が分かる。
上限は前段と後段の両方で上げる。

nginx を通過したあとに 413 が返るなら、アプリ側の上限に当たっている。
その場合は、応答の本文に nginx の署名が出ず、nginx の error.log にも行が増えない。

よくある原因

  1. client_max_body_size を書いていない。
    既定の 1m を超える本文はすべて 413 になる。
  2. location の値が server の値を上書きしている。server に 20m と書いても、その location に 1m とあれば、そこを通るリクエストの上限は 1m になる。
  3. 設定を書き換えたあと reload していない。
    ファイルを保存しただけでは、動いている nginx の上限は変わらない。
  4. nginx を 2 段に重ねている。
    前段の上限を上げても、後段が既定の 1m のままなら後段が 413 を返す。