Skip to content

How to correctly configure Nginx's client_max_body_size | Troubleshooting upload limits

Category: Nginx / Server Configuration
This article is currently available in Japanese only. We are working on translations.

When implementing file uploads in Nginx, the issue of "small files upload fine but large files result in a 413 error" is encountered very frequently. The cause is almost always insufficient <code>client_max_body_size</code> configuration. However, simply fixing the Nginx configuration often doesn't resolve the issue, and you need a comprehensive understanding including PHP's <code>upload_max_filesize</code> and <code>post_max_size</code>, as well as timeout settings. This article systematically explains all configuration items related to upload limits.

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 Requests over the limit are rejected with 413 before reaching upstream
Diagram: allow/deny by client_max_body_size

Default Value and Role of client_max_body_size

Nginx has a <code>client_max_body_size</code> directive that limits the maximum size of request bodies from clients. The default value is <code>1m</code> (1 MiB). Requests exceeding this limit are immediately rejected with a <code>413 Request Entity Too Large</code> error.

Since the default is as small as 1m, you'll quickly hit the limit even when uploading a single image or PDF. In actual production environments, you need to raise this value appropriately according to your use case.

Configuration location: differences between http / server / location

<code>client_max_body_size</code> can be set at any configuration level in Nginx (http / server / location). More specific scope settings take precedence.

# 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;
        }
    }
}

Setting a larger value only for upload-specific endpoints while keeping others small is the security best practice. You can specify <code>0</code> for unlimited, but this increases DoS attack risk and is not recommended.

413 Request Entity Too Large error: causes and solutions

We will organize the causes and countermeasures for 413 errors.

Cause Points to Check Countermeasure
Nginx Limit Exceeded <code>client_max_body_size</code> in nginx.conf Increase the value
PHP limit exceeded <code>upload_max_filesize</code> in php.ini Increase the value
Exceeded limit for entire POST body <code>post_max_size</code> in php.ini Make it larger than upload_max_filesize
Reverse Proxy Limits Upstream Nginx or load balancer configuration Check proxies at each stage

After changing Nginx configuration, you must always reload.

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

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

# または systemd 経由
systemctl reload nginx

Relationship with PHP's upload_max_filesize / post_max_size

Simply raising Nginx's <code>client_max_body_size</code> is not enough. If the backend is PHP, there are independent limits at the PHP level as well. Upload succeeds only when all three of these settings are set to appropriate values.

; 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

The relationships between important configuration values are as follows.

  • client_max_body_size(Nginx)post_max_size(PHP)upload_max_filesize(PHP)
  • If Nginx rejects a request, the processing never reaches PHP
  • <code>post_max_size</code> is the size limit for the entire POST body, including multiple file uploads and non-file form fields

Importance of proxy_read_timeout / proxy_send_timeout

When uploading large files, timeout settings are also important. The default <code>proxy_read_timeout</code> is 60 seconds, and if the upload takes time, the process will be interrupted.

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;
}

It is recommended to set different timeout values for upload endpoints and regular API endpoints.

Configuration in Docker (nginx.conf Mounting)

In Docker environments, custom nginx.conf or conf.d files are mounted into containers to apply configuration.

# 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;
    }
}

Configuration Verification Command

To check what value <code>client_max_body_size</code> is set to in your current Nginx configuration, it's convenient to expand all settings with <code>nginx -T</code> and then grep the result.

# 全設定を展開して 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"

Common configuration errors and how to fix them

  • <strong>Unit error</strong>: <code>client_max_body_size 100</code> defaults to bytes. Always specify a unit like <code>100m</code>
  • <strong>Hierarchy oversight</strong>: You think you're overriding within a location block, but a higher-level server block or http block is taking effect
  • <strong>Forgetting to reload</strong>: Configuration changes won't take effect unless you run <code>nginx -s reload</code>
  • <strong>Multiple server blocks</strong>: Another conf.d file loaded via include is conflicting
  • <strong>Mismatch with PHP</strong>: Even after increasing Nginx limits, if PHP's <code>upload_max_filesize</code> remains low, errors other than 413 may occur

Test files for this article (free)

  • → <a href="/ja/files/threshold/" class="text-primary-600 dark:text-primary-400 hover:underline">Boundary Value Test Files</a> — Reproduce errors at the client_max_body_size configuration threshold
  • → <a href="/ja/files/images/png/" class="text-primary-600 dark:text-primary-400 hover:underline">PNG Test Images List</a> — Verify Nginx limits with PNG images of various sizes

Related articles

  • → <a href="/ja/blog/how-to-test-upload-limit/" class="text-primary-600 dark:text-primary-400 hover:underline">How to Properly Test File Upload Limits</a>
  • → <a href="/ja/blog/multipart-form-data-overhead/" class="text-primary-600 dark:text-primary-400 hover:underline">Calculating multipart/form-data Overhead Accurately</a>
  • → <a href="/ja/blog/mb-vs-mib-file-size/" class="text-primary-600 dark:text-primary-400 hover:underline">Difference Between MB and MiB | Correct Understanding of File Size Units</a>

Frequently Asked Questions

What is the default value of Nginx's client_max_body_size?

The default is 1m (1 megabyte). Requests exceeding this will result in a 413 Request Entity Too Large error.

Where Should client_max_body_size Be Configured?

You can set it in the <code>http</code>, <code>server</code>, or <code>location</code> block. If you want to change only a specific endpoint, write it in the <code>location</code> block.

What is the relationship between Nginx and PHP upload settings?

Nginx checks requests with client_max_body_size before they reach PHP. You also need to configure PHP's upload_max_filesize and post_max_size accordingly.