nginx の 413 は、リクエストの本文(アップロードするファイルなど)が client_max_body_size を超えたときに返ります。既定値は 1m(1MB)です。 大きくするには、アップロードを受ける場所に1行書いて reload します。

server {
    server_name example.com;
    client_max_body_size 20m;     # このサイト全体で 20MB まで

    location /api/upload {
        client_max_body_size 100m;   # ここだけ 100MB まで
        proxy_pass http://app:8080;
    }
}
sudo nginx -t && sudo systemctl reload nginx

nginx 1.24.0 で、何も書かない状態(既定 1m)にアップロードした結果です。1,048,576 バイト(1MiB)ちょうどまでが通り、1バイト超えると 413 でした。

送った本文 結果
1,048,576 バイト 200
1,048,577 バイト 413
5,242,880 バイト 413
1,048,576 バイトのファイルを curl -F(multipart)で 413(区切り文字の分だけ本文が大きくなる)
1,048,000 バイトのファイルを curl -F で 200(本文は 1,048,210 バイト)

確認環境:Ubuntu 24.04 の nginx 1.24.0(apt で入れたもの)を、curl 8.5.0 で試しました。アプリ側は PHP 8.4.21 の組み込みサーバー、Node.js 22.22.2 と Express 5.3.0・multer 2.4.0 で動かし、Spring Boot の既定値はソース(MultipartProperties・TomcatServerProperties)で確かめています。ロードバランサーなどの上限は各社の公式ドキュメントで確かめています(確認日 2026年10月13日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「nginx 413 Request Entity Too Largeの直し方」

413 が返るときに起きていること

nginx が返す 413 の応答と、エラーログです。

HTTP/1.1 413 Request Entity Too Large
Server: nginx/1.24.0 (Ubuntu)
Content-Type: text/html
Content-Length: 192
Connection: close

<html>
<head><title>413 Request Entity Too Large</title></head>
<body>
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>nginx/1.24.0 (Ubuntu)</center>
</body>
</html>
[error] 15691#15691: *3 client intended to send too large body: 1048577 bytes, client: 127.0.0.1, server: , request: "POST /upload HTTP/1.1", host: "127.0.0.1:18115"

client intended to send too large body がエラーログにあれば、nginx の client_max_body_size が原因です。 ログが無ければ、手前のロードバランサーか、後ろのアプリが 413 を返しています。

確かめること nginx が返した 413 アプリが返した 413
エラーログ client intended to send too large body 何も出ない(nginx は中継しただけ)
応答の本文 <center><h1>413 Request Entity Too Large</h1></center> の HTML アプリの形式(Express なら JSON など)
アクセスログのステータス 413 413

413 は、本文を全部受け取る前に返ります。 nginx はリクエストヘッダーの Content-Length を見て判断するので、return 200 だけの location でも 413 になりました。手元で 5MB を送ったときの、curl が実際に送った量です。

送り方 結果 curl が送った量
Expect: 100-continue あり(curl の既定) 413 0 バイト(本文を送る前に断られた)
Expect: を外した 413 327,680 バイト(送っている途中で接続を閉じられた)
Transfer-Encoding: chunked(大きさを先に言わない) 413 3,080,004 バイト

chunked のときは、受け取りながら数えて、超えた時点で 413 にします。エラーログは client intended to send too large chunked body: 1048384+65524 bytes でした。公式ドキュメントにも「ブラウザはこのエラーを正しく表示できない」とあります。 本文を送っている途中で接続を閉じられると、ブラウザは 413 の画面ではなく「接続がリセットされました」などを表示することがあります。

RFC 9110(HTTP の仕様)では、413 の名前は「Content Too Large」に変わりました。nginx 1.24.0 の応答は「Request Entity Too Large」のままです。

client_max_body_size の書き方

項目 内容
書ける場所 http・server・location
既定値 1m
単位 なし(バイト)・k/K・m/M・g/G(1024 倍)
0 大きさを確かめない(無制限)
反映 nginx -t で確かめてから systemctl reload nginx

http・server・location のどこに書くか

内側に書いた値が勝ちます。 内側に書かなければ、外側の値を引き継ぎます。手元で3か所に書き分けて試した結果です。

http {
    client_max_body_size 2m;                 # http:全部のサイトの既定

    server {                                 # サイト A(:18115)
        location / { proxy_pass http://127.0.0.1:18200; }
        location /api/upload {
            client_max_body_size 20m;        # ここだけ 20m
            proxy_pass http://127.0.0.1:18200;
        }
        location /nolimit {
            client_max_body_size 0;          # 確かめない
            proxy_pass http://127.0.0.1:18200;
        }
    }
    server {                                 # サイト B(:18116)
        client_max_body_size 5m;
        location / { proxy_pass http://127.0.0.1:18200; }
    }
}
送り先 効いた値 3MB 10MB 30MB
サイト A の / http の 2m 413 413 413
サイト A の /api/upload location の 20m 200 200 413
サイト A の /nolimit location の 0 200 200 200
サイト B の / server の 5m 200 413 413
書く場所 向いている使い方
location アップロードを受ける URL だけ大きくする。ほかの URL は小さいまま守れる
server そのサイト全体で大きくする
http サーバーにある全部のサイトで同じにする(Ubuntu なら /etc/nginx/nginx.conf か /etc/nginx/conf.d/*.conf)

location を正規表現などで分けている場合は、リクエストがどの location に入るかで値が決まります。 アップロードの URL がどの location に入るかは、関連記事「nginx location書き方|優先順位とtry_filesをcurlで検証」で扱っています。

書き間違えたときのエラー

手元で nginx -t を通した結果です。

書いたもの nginx -t
client_max_body_size 10MB; "client_max_body_size" directive invalid value
client_max_body_size 10mb; "client_max_body_size" directive invalid value
if の中に書いた "client_max_body_size" directive is not allowed here
同じ場所に2回書いた "client_max_body_size" directive is duplicate
client_max_body_size 1g; 成功

単位は1文字(m・g)です。MB・mb は書けません。 設定を直しても変わらない場合は、別のファイル(sites-enabled の別のサイト、conf.d)の server が使われていないか、sudo nginx -T | grep -n client_max_body_size で全部の設定を確かめます。

0(無制限)にしてよいか

0 は大きさを確かめないだけで、ほかの制限は残ります。 大きな本文はディスクの一時ファイルに書かれるので、ディスクを使い切られるおそれがあります。手元でも、1MB を超える本文を受けたときに次の警告が出ました。

[warn] 15691#15691: *10 a client request body is buffered to a temporary file .../body/0000000003, ...
一緒に見直す設定 既定値 意味
client_body_buffer_size 8k か 16k(メモリページ2つ分) これを超える本文は一時ファイルに書く
client_body_timeout 60s 本文を受け取る途中で、この時間何も来なければ 408
proxy_read_timeout 60s 後ろのアプリの応答を待つ時間。大きなファイルの処理で 504 になりやすい
proxy_request_buffering on on なら本文を全部受けてからアプリに送る

アップロードの URL だけを、必要な大きさにする書き方が安全です。 上限を決めない場合でも、アプリ側でファイルの大きさを確かめます。ファイルアップロードの守り方は、関連記事「ファイルアップロードのセキュリティ対策|実装コードと検証チェックリスト」で扱っています。

413 のエラーページを差し替える

error_page 413 で、nginx の既定の HTML を自分のページや JSON に差し替えられます。 手元で確かめた設定です。

server {
    listen 80;
    client_max_body_size 1m;
    root /var/www/html;
    charset utf-8;                         # 日本語のページを返すとき

    # 画面向け:HTML を返す
    error_page 413 /errors/413.html;
    location = /errors/413.html { internal; }

    # API 向け:JSON を返す
    location /api/ {
        error_page 413 = @too_large_json;
        proxy_pass http://127.0.0.1:8080;
    }
    location @too_large_json {
        default_type application/json;
        return 413 '{"error":"payload_too_large","limit":"1MB"}\n';
    }

    location / { proxy_pass http://127.0.0.1:8080; }
}
HTTP/1.1 413 Request Entity Too Large
Content-Type: application/json
Content-Length: 44
Connection: close

{"error":"payload_too_large","limit":"1MB"}
書き方 意味
error_page 413 /errors/413.html; 413 のときに /errors/413.html を返す。ステータスは 413 のまま
location = /errors/413.html { internal; } 外から直接開くと 404(手元でも 404 になった)
error_page 413 = @名前; 名前付き location で応答を作る
return 413 '...'; ステータスと本文をその場で返す

ブラウザから別ドメインの API に送る場合、413 に CORS のヘッダーが付かないと、ブラウザには CORS のエラーとして見えます。 add_header は既定で 2xx・3xx の応答にしか付きません。手元でも、always を付けたヘッダーだけが 413 の応答に付きました。

add_header Access-Control-Allow-Origin https://app.example.com always;

手前と後ろの上限との関係

nginx を大きくしても、手前のロードバランサーや後ろのアプリの上限のほうが小さければ、そちらで止まります。 経路のいちばん小さい値が実際の上限です。

flowchart LR
    B["ブラウザ"] --> CDN["CDN・ロードバランサー<br/>(Cloudflare・API Gateway など)"]
    CDN --> N["nginx<br/>client_max_body_size"]
    N --> A["アプリ<br/>(Spring・PHP・Node)"]
場所 設定 既定値(出典) 超えたとき
nginx client_max_body_size 1m(手元で確認) 413
Kubernetes の ingress-nginx 注釈 nginx.ingress.kubernetes.io/proxy-body-size 1m(ConfigMap の proxy-body-size) 413
Apache httpd LimitRequestBody 1GiB(2.4.54 以降。2.4.53 までは無制限) 413
Cloudflare プランで決まる Free・Pro 100MB、Business 200MB 413
Amazon API Gateway(REST API) 変更できない 10MB 413
ALB → Lambda 変更できない 1MB ALB がエラーを返す
Spring Boot spring.servlet.multipart.max-file-size 1MB(ソースで確認) MaxUploadSizeExceededException
Spring Boot spring.servlet.multipart.max-request-size 10MB(ソースで確認) 同上
Spring Boot(Tomcat) server.tomcat.max-http-form-post-size 2MB(ソースで確認) フォームの値が読めない
PHP upload_max_filesize 2M(手元で確認) $_FILES の error が 1
PHP post_max_size 8M(手元で確認) $_POST・$_FILES が空
Express express.json({ limit }) 100kb(手元で確認) 413 PayloadTooLargeError
multer limits.fileSize 無制限 LIMIT_FILE_SIZE

ingress-nginx は、Kubernetes の公式ブログで 2026年3月までで保守を終えると案内されています。

PHP:413 ではなく 200 で中身が空になる

PHP は、上限を超えても 413 を返さず、200 で $_POST・$_FILES が空になります。 手元で PHP 8.4.21(upload_max_filesize = 2M、post_max_size = 8M)に送った結果です。

送ったファイル $_POST $_FILES['file']['error']
1MB 1件 0(成功)
3MB(upload_max_filesize 超え) 1件 1(UPLOAD_ERR_INI_SIZE)
10MB(post_max_size 超え) 0件 $_FILES も空

10MB のときは、ログに次の警告が出ました。

PHP Warning:  PHP Request Startup: POST Content-Length of 10486071 bytes exceeds the limit of 8388608 bytes in Unknown on line 0
; php.ini(php-fpm なら /etc/php/8.x/fpm/php.ini。変えたら php-fpm を再起動)
upload_max_filesize = 20M
post_max_size = 25M        ; ファイル+ほかのフォーム項目より大きくする

post_max_size は upload_max_filesize より大きくします。$_POST が空のときは、$_SERVER['CONTENT_LENGTH'] と post_max_size を比べると、上限を超えたかが分かります。

Node.js(Express・multer)

Express の express.json() の既定は 100kb で、超えると 413 になります。 手元で 90,000 文字は 200、102,400 文字の JSON は PayloadTooLargeError(status 413、request entity too large)でした。multer は limits.fileSize を書かないと上限がありません。

const express = require('express');
const multer = require('multer');
const app = express();

app.use(express.json({ limit: '5mb' }));                       // JSON の上限
const upload = multer({
  storage: multer.memoryStorage(),
  limits: { fileSize: 2 * 1024 * 1024 },                       // ファイル1つの上限 2MB
});
app.post('/file', upload.single('file'), (req, res) => res.json({ size: req.file.size }));

app.use((err, req, res, next) => {                             // 413 を JSON で返す
  if (err.code === 'LIMIT_FILE_SIZE' || err.type === 'entity.too.large') {
    return res.status(413).json({ error: 'payload_too_large' });
  }
  next(err);
});
app.listen(3000);

手元で 3MB のファイルを送ると、multer は MulterError: File too large(code: LIMIT_FILE_SIZE)を出し、上の処理で 413 を返しました。

Spring Boot

# application.yml
spring:
  servlet:
    multipart:
      max-file-size: 20MB        # ファイル1つ(既定 1MB)
      max-request-size: 25MB     # リクエスト全体(既定 10MB)
server:
  tomcat:
    max-swallow-size: 30MB       # 上限を超えた本文を読み捨てる量(既定 2MB)

Spring Boot のソースでは、max-file-size が 1MB、max-request-size が 10MB、Tomcat の max-swallow-size と max-http-form-post-size が 2MB、max-part-count が 50 です。上限を超えると MaxUploadSizeExceededException になります。実装と例外の扱いは、関連記事「Spring Bootファイルアップロード|MultipartFile実装コード全文」で扱っています。

3か所(nginx・Spring・Tomcat)の値をそろえないと、どこで止まったかで応答の形が変わります。 外側の nginx を少し大きめにして、アプリで分かりやすいエラーを返すか、nginx で止めて error_page で JSON を返すかを決めておきます。

よくある質問

Q. 設定したのに 413 のままです。 A. 次の順で確かめます。① sudo nginx -T | grep client_max_body_size で、リクエストが入る server・location に書かれているか ② systemctl reload nginx したか ③ エラーログに client intended to send too large body が出ているか(出ていなければ nginx 以外)④ 手前のロードバランサー・CDN・ingress の上限。

Q. Docker の公式 nginx イメージではどこに書きますか? A. /etc/nginx/conf.d/default.conf の server の中か、/etc/nginx/conf.d/ に client_max_body_size 20m; だけを書いたファイルを置くと、http の中に読み込まれます。

Q. 上限はどのくらいにすればよいですか? A. 受け付けるファイルの最大の大きさに、multipart の区切りやほかの項目の分を少し足した値が目安です。手元では、1,048,000 バイトのファイルを curl -F で送ると、本文は 1,048,210 バイトになりました。

Q. 413 を返したあと、ブラウザが「接続がリセットされました」と表示します。 A. nginx が本文を受け取る途中で接続を閉じたためです。ブラウザ側で送る前にファイルの大きさを確かめる(file.size)と、利用者に分かりやすいメッセージを出せます。

まとめ

  • 413 は本文が client_max_body_size(既定 1m) を超えたとき。1,048,577 バイトから 413
  • 書ける場所は http・server・location。内側が勝つ。アップロードの URL だけ大きくするのが安全
  • 単位は m・g。MB は invalid value。0 は確かめない(ディスクの一時ファイルに注意)
  • エラーログの client intended to send too large body があれば nginx が原因
  • error_page 413 で HTML・JSON に差し替え。CORS のヘッダーは always を付ける
  • 経路でいちばん小さい上限が効く。PHP は 200 で中身が空、Express の JSON は 100kb、Spring は 1MB/10MB

nginx の proxy_pass の基本と 502/504 は、関連記事「Nginxリバースプロキシ設定|proxy_passの書き方と502/504対処」で扱っています。

参考・出典

確認日はいずれも 2026年10月13日です。

  • nginx「Module ngx_http_core_module(client_max_body_size・client_body_buffer_size・error_page)」:https://nginx.org/en/docs/http/ngx_http_core_module.html
  • nginx「Module ngx_http_headers_module(add_header)」:https://nginx.org/en/docs/http/ngx_http_headers_module.html
  • RFC 9110「HTTP Semantics」15.5.14 413 Content Too Large:https://www.rfc-editor.org/rfc/rfc9110#name-413-content-too-large
  • PHP マニュアル「php.ini ディレクティブ(post_max_size・upload_max_filesize)」:https://www.php.net/manual/ja/ini.core.php
  • PHP マニュアル「エラーメッセージの説明(ファイルアップロード)」:https://www.php.net/manual/ja/features.file-upload.errors.php
  • Express「express.json()」:https://expressjs.com/en/5x/api.html#express.json
  • multer:https://github.com/expressjs/multer
  • Spring Boot のソース(MultipartProperties・TomcatServerProperties):https://github.com/spring-projects/spring-boot
  • Apache HTTP Server「LimitRequestBody」:https://httpd.apache.org/docs/2.4/mod/core.html#limitrequestbody
  • ingress-nginx「ConfigMap(proxy-body-size)」:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
  • Kubernetes Blog「Ingress NGINX Retirement」:https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/
  • Cloudflare「Workers limits(Request limits)」:https://developers.cloudflare.com/workers/platform/limits/
  • Amazon API Gateway「Quotas」:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-execution-service-limits-table.html
  • Elastic Load Balancing「Lambda functions as targets」:https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「nginx 413 Request Entity Too Largeの直し方」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?