コンテンツにスキップ

Nginxのclient_max_body_sizeを正しく設定する方法|アップロード上限のトラブル解決

カテゴリ:Nginx・サーバー設定

Nginxでファイルアップロードを実装したとき、「小さいファイルは送れるのに大きいファイルを送ると 413 エラーになる」という問題は非常によく遭遇します。その原因のほとんどは client_max_body_size の設定不足です。しかし、Nginxの設定だけ直しても解決しないケースも多く、PHPの upload_max_filesizepost_max_size、さらにはタイムアウト設定まで含めたトータルな理解が必要です。本記事では、アップロード上限に関わるすべての設定項目を体系的に解説します。

client_max_body_size 10m 5 MB POST 10 MB POST 20 MB POST nginx limit: 10 MB 200 OK 200 OK 413 Too Large 上限を超えるリクエストは upstream に届く前に 413 で拒否される
図: client_max_body_size による許可/拒否の判定

client_max_body_size のデフォルト値と役割

Nginxには client_max_body_size というディレクティブがあり、クライアントからのリクエストボディの最大サイズを制限します。デフォルト値は 1m(1 MiB)です。これを超えるリクエストは即座に 413 Request Entity Too Large エラーとして拒否されます。

デフォルトが 1m と非常に小さいため、画像1枚やPDFのアップロードでもすぐに上限に達してしまいます。実際のプロダクション環境では用途に応じてこの値を適切に引き上げる必要があります。

設定場所:http / server / location の違い

client_max_body_size は Nginx の設定階層(http / server / location)のどこにでも記述できます。より詳細なスコープの設定が優先されます。

# http ブロック(全サーバー共通)
http {
    client_max_body_size 10m;

    server {
        listen 80;
        server_name example.com;

        # server ブロック(このバーチャルホスト全体)
        client_max_body_size 50m;

        location /upload {
            # location ブロック(このパスのみ)
            # より大きなファイルを許可したい場合
            client_max_body_size 200m;

            proxy_pass http://app;
        }

        location /api {
            # APIエンドポイントはデフォルト(1m)のままにする例
            client_max_body_size 1m;
        }
    }
}

アップロード専用のエンドポイントだけ大きい値を設定し、他は小さい値に抑えるのがセキュリティ上の好ましいアプローチです。無制限にしたい場合は 0 を指定しますが、DoS攻撃のリスクが増すため推奨しません。

413 Request Entity Too Large エラーの原因と解決

413 エラーが発生する原因と対処法を整理します。

原因 確認箇所 対処法
Nginx の制限超過 nginx.conf の client_max_body_size 値を引き上げる
PHP の制限超過 php.ini の upload_max_filesize 値を引き上げる
POSTボディ全体の制限超過 php.ini の post_max_size upload_max_filesize より大きくする
リバースプロキシの制限 上流のNginxやロードバランサー設定 各段のプロキシを確認する

Nginx の設定変更後は必ずリロードが必要です。

# 設定の文法チェック
nginx -t

# 設定のリロード(サービス停止なし)
nginx -s reload

# または systemd 経由
systemctl reload nginx

PHPの upload_max_filesize / post_max_size との関係

Nginx の client_max_body_size を引き上げただけでは不十分です。バックエンドが PHP の場合、PHPレベルでも独立した制限があります。この3つの設定がすべて適切な値になって初めてアップロードが成功します。

; php.ini の設定
; 1ファイルあたりの上限
upload_max_filesize = 100M

; POSTリクエスト全体の上限(upload_max_filesize より大きくする)
; multipart/form-data のオーバーヘッド分を見込んで多めに設定
post_max_size = 110M

; メモリ上限(post_max_size より大きくする)
memory_limit = 256M

; アップロード処理の実行時間(大容量ファイル用に延ばす)
max_execution_time = 300
max_input_time = 300

重要な設定値の関係は以下のとおりです。

  • client_max_body_size(Nginx)post_max_size(PHP)upload_max_filesize(PHP)
  • Nginx がリクエストを拒否してしまうと、PHP まで処理が届かない
  • post_max_size は複数ファイルのアップロードや、ファイル以外のフォームフィールドも含んだ POSTボディ全体のサイズ制限

proxy_read_timeout / proxy_send_timeout の重要性

大容量ファイルのアップロードでは、タイムアウト設定も重要です。デフォルトの proxy_read_timeout は 60 秒で、アップロードに時間がかかると処理が中断されてしまいます。

location /upload {
    client_max_body_size 500m;

    proxy_pass http://app_backend;

    # バックエンドからのレスポンス待機時間
    # 大容量ファイルの処理には長めに設定
    proxy_read_timeout 600s;

    # クライアントへのデータ送信待機時間
    proxy_send_timeout 600s;

    # バックエンドへの接続タイムアウト
    proxy_connect_timeout 60s;

    # クライアントのリクエストボディ受信タイムアウト
    # 2回の連続した読み取り操作の間の時間
    client_body_timeout 120s;
}

アップロード用エンドポイントと通常のAPIエンドポイントでタイムアウト値を分けて設定することが推奨されます。

Dockerでの設定(nginx.conf マウント)

Docker 環境では、カスタムの nginx.conf または conf.d ファイルをコンテナにマウントして設定を反映します。

# Dockerfile でのカスタム設定追加
FROM nginx:alpine

# カスタム設定ファイルをコピー
COPY ./nginx/conf.d/upload.conf /etc/nginx/conf.d/upload.conf

# デフォルト設定を完全に置き換える場合
# COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# docker-compose.yml でのボリュームマウント
version: '3.8'
services:
  nginx:
    image: nginx:alpine
    volumes:
      # ディレクトリごとマウント(変更が即反映される)
      - ./nginx/conf.d:/etc/nginx/conf.d
      # または特定ファイルだけマウント
      # - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "80:80"
# nginx/conf.d/upload.conf
server {
    listen 80;
    server_name localhost;

    # グローバルのアップロード上限
    client_max_body_size 100m;

    location / {
        proxy_pass http://app:9000;
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }

    location /upload {
        client_max_body_size 500m;
        proxy_pass http://app:9000;
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
    }
}

設定確認コマンド

現在の Nginx 設定で client_max_body_size がどの値になっているか確認するには、nginx -T で全設定を展開してから grep するのが便利です。

# 全設定を展開して client_max_body_size を検索
nginx -T | grep -i body_size

# 出力例:
#   client_max_body_size 1m;   ← デフォルト(http ブロック)
#   client_max_body_size 100m; ← カスタム設定(server ブロック)

# 設定ファイルのパスも確認
nginx -T | grep "# configuration"

# 特定の設定ファイルだけチェック
nginx -t -c /etc/nginx/nginx.conf

# 現在読み込まれている設定のダンプ
nginx -T 2>/dev/null | grep -A1 "client_max"

よくある設定ミスと対処法

  • 単位の誤りclient_max_body_size 100 はバイト指定になる。100m のように単位を必ず付ける
  • 階層の見落とし:location ブロック内で上書きしているつもりが、上位の server ブロックや http ブロックが効いているケース
  • リロード忘れ:設定ファイルを変更しても nginx -s reload しないと反映されない
  • 複数 server ブロック:include で読み込まれる別の conf.d ファイルが競合している
  • PHPとの不一致:Nginx を上げても PHP の upload_max_filesize が低いままで 413 以外のエラーが出る

この記事で使えるテストファイル(無料)

よくある質問

Nginxのclient_max_body_sizeのデフォルト値は?

デフォルトは1m(1メガバイト)です。これを超えるリクエストは413 Request Entity Too Largeエラーになります。

client_max_body_sizeはどこに設定すべき?

http、server、locationブロックのいずれかに設定できます。特定のエンドポイントだけ変更したい場合はlocationブロックに記述します。

NginxとPHPのアップロード設定の関係は?

NginxのリクエストがPHPに到達する前にclient_max_body_sizeでチェックされます。PHP側のupload_max_filesizeとpost_max_sizeも合わせて設定する必要があります。