Skip to content

413 Request Entity Too Large error: causes and solutions | Complete guide for Nginx, PHP, and Apache

Category: Server / HTTP

When implementing file upload functionality, you may suddenly see a "413 Request Entity Too Large" error in your browser. This HTTP status code is returned when the size of the request body sent exceeds the server's configured limit. This article comprehensively covers the configuration locations for Nginx, PHP, and Apache, systematically explaining how to identify the cause and resolve the issue.

What is a 413 Error

The HTTP 413 status code (renamed to "Content Too Large" in RFC 9110) is returned when the request body sent by the client exceeds the server's maximum processable size. This occurs not only for file uploads, but also for large JSON payloads or Base64-encoded data transmission.

When this error occurs, the server rejects the request itself, so the connection is closed before processing reaches the application code (PHP, Python, etc.). As a result, no record is left in the application log, and you need to check the web server's error log.

Nginx: client_max_body_size Configuration

By default, Nginx has client_max_body_size set to 1MB. For sites that accept image or PDF uploads, you will almost certainly need to increase this value.

# /etc/nginx/nginx.conf(グローバル設定)
http {
    # すべての仮想ホストに適用
    client_max_body_size 100m;

    server {
        listen 80;
        server_name example.com;

        # このサーバーブロック内のみに適用(httpの値を上書き)
        client_max_body_size 50m;

        location /api/upload {
            # このlocationのみに適用(serverの値を上書き)
            client_max_body_size 200m;

            proxy_pass http://backend;
        }
    }
}

The priority order of settings is location > server > http. If you want to increase the limit for only a specific upload endpoint, specifying it in the location block is a best practice.

# 設定変更後はNginxをリロード
sudo nginx -t          # 構文チェック
sudo systemctl reload nginx  # リロード(ダウンタイムなし)

# エラーログの確認
tail -f /var/log/nginx/error.log
# 413エラー時のログ例:
# client intended to send too large body: 10485760 bytes

PHP: Relationship between upload_max_filesize / post_max_size / memory_limit

PHP has multiple size limits, and you must understand the relationship between them correctly. Always configure to satisfy the following inequality.

; php.ini の設定
; 必ず以下の関係を維持すること:
; upload_max_filesize <= post_max_size <= memory_limit

; 1ファイルあたりの最大サイズ
upload_max_filesize = 50M

; POSTリクエスト全体の最大サイズ(複数ファイルの合計 + フォームデータ)
post_max_size = 100M

; PHPスクリプトが使用できる最大メモリ
memory_limit = 256M

; ファイルアップロードの最大数
max_file_uploads = 20

; アップロードの一時保存先
upload_tmp_dir = /tmp
Directive Default Value Scope of impact
upload_max_filesize 2M Maximum file size
post_max_size 8M Entire POST request (file + form data)
memory_limit 128M Maximum memory usage during script execution
max_file_uploads 20 Number of files that can be uploaded simultaneously
max_execution_time 30 Maximum number of seconds for script execution (extension required for large files)
max_input_time 60 Maximum seconds allowed for analyzing input data
// 現在のPHP設定値を確認するスクリプト
echo 'upload_max_filesize: ' . ini_get('upload_max_filesize') . PHP_EOL;
echo 'post_max_size: '       . ini_get('post_max_size') . PHP_EOL;
echo 'memory_limit: '        . ini_get('memory_limit') . PHP_EOL;
echo 'max_file_uploads: '    . ini_get('max_file_uploads') . PHP_EOL;
echo 'max_execution_time: '  . ini_get('max_execution_time') . PHP_EOL;

// php.ini の場所を確認
echo 'Loaded php.ini: ' . php_ini_loaded_file() . PHP_EOL;

Apache: LimitRequestBody Configuration

In Apache, use the LimitRequestBody directive to set a limit on the request body. The default is 0 (unlimited), but it is recommended to set an appropriate limit for security.

# /etc/apache2/apache2.conf または .htaccess
# バイト単位で指定(100MB = 104857600 bytes)

# グローバル設定
LimitRequestBody 104857600

# 特定のディレクトリのみ
<Directory "/var/www/html/uploads">
    LimitRequestBody 209715200
</Directory>

# 特定のURLパスのみ
<Location "/api/upload">
    LimitRequestBody 209715200
</Location>

# .htaccess での設定(AllowOverride が必要)
# php_value upload_max_filesize 50M
# php_value post_max_size 100M

Common combination mistakes

The tricky part of 413 errors is that there are multiple layers, each with their own size limits. Even if you change one setting, requests are frequently blocked at another layer.

Case 1: Passes through Nginx but rejected by PHP

If Nginx's client_max_body_size is set to 100m but PHP's upload_max_filesize remains 2M, a 50MB file will pass through Nginx but be ignored by PHP. In this case, the HTTP status will return 200, but the file will be empty and $_FILES will contain error code 1 (UPLOAD_ERR_INI_SIZE).

Case 2: upload_max_filesize is sufficient but post_max_size is not

Even if you set upload_max_filesize = 50M, if post_max_size = 8M remains unchanged, any request exceeding 8MB will be entirely discarded. In this case, both $_POST and $_FILES become empty arrays, which is confusing behavior.

Case 3: Oversight in reverse proxy configuration

When using Nginx as a reverse proxy with Apache + PHP-FPM in the backend, you must set limits in all three: Nginx, Apache, and PHP.

# Nginx リバースプロキシの設定
server {
    client_max_body_size 100m;

    location / {
        proxy_pass http://127.0.0.1:8080;

        # プロキシ関連のタイムアウトも延長(大容量ファイル対策)
        proxy_read_timeout 300;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;

        # バッファリングの設定
        proxy_request_buffering on;
        proxy_buffering on;
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
    }
}

Debug Procedure

When a 413 error occurs, identify the cause using the following steps.

# 1. どのレイヤーでブロックされているか確認
# Nginx のエラーログを確認
tail -n 50 /var/log/nginx/error.log | grep "too large"

# 2. PHP の設定値を確認
php -i | grep -E "upload_max|post_max|memory_limit"

# 3. PHP-FPM の設定ファイルを確認(php.ini とは別の場合がある)
php-fpm -i | grep -E "upload_max|post_max"
# または
find /etc -name "php.ini" -o -name "www.conf" | xargs grep -l "upload_max"

# 4. Apache の設定を確認
apachectl -t -D DUMP_RUN_CFG 2>/dev/null | grep -i limit
grep -r "LimitRequestBody" /etc/apache2/ /etc/httpd/

# 5. curl で実際にテスト(10MBのダミーファイルを送信)
dd if=/dev/zero of=/tmp/test_10mb.bin bs=1M count=10
curl -v -X POST -F "file=@/tmp/test_10mb.bin" https://example.com/api/upload

# 6. レスポンスヘッダーを確認
curl -I -X POST -F "file=@/tmp/test_10mb.bin" https://example.com/api/upload

Testing method

After changing settings, it is important to test by uploading files of different sizes. DevLab provides files for boundary value testing. Test around the upper limit (for example, if the limit is 50MB, test with 49MB, 50MB, and 51MB) and verify that the behavior is as expected.

# JavaScript での送信テスト例
# 指定サイズのBlobを作成して送信する方法

# <script>
# async function testUpload(sizeMB) {
#     const blob = new Blob(
#         [new ArrayBuffer(sizeMB * 1024 * 1024)],
#         { type: 'application/octet-stream' }
#     );
#     const formData = new FormData();
#     formData.append('file', blob, 'test.bin');
#
#     const response = await fetch('/api/upload', {
#         method: 'POST',
#         body: formData
#     });
#     console.log(sizeMB + 'MB:', response.status, response.statusText);
# }
#
# // 境界値テスト
# testUpload(1);    // 1MB  - 通常は成功
# testUpload(10);   // 10MB - 設定による
# testUpload(50);   // 50MB - 設定による
# testUpload(100);  // 100MB - 通常は失敗
# </script>

Recommended settings summary for each server

Layer Directive Recommended Value (supports 50MB uploads)
Nginx client_max_body_size 60m (with some margin)
PHP upload_max_filesize 50M
PHP post_max_size 55M (larger than upload_max_filesize)
PHP memory_limit 256M
Apache LimitRequestBody 62914560 (60 MB, in bytes)

Test files for this article (free)

❓ Frequently Asked Questions

What is a 413 Request Entity Too Large error?
HTTP 413 is returned when the request body a client sent exceeds the limit configured on the server. It shows up most often during file uploads, where Nginx, PHP and Apache each impose their own ceiling.
What is the default value of client_max_body_size in Nginx?
1 MB. Any site that accepts uploads needs to raise it in the http, server or location block. After changing it, run nginx -t to check the syntax and reload with systemctl reload nginx.
What is the difference between upload_max_filesize and post_max_size?
upload_max_filesize caps a single file; post_max_size caps the whole POST request — all files plus the form data. post_max_size must be the larger of the two. Exceed post_max_size and both $_POST and $_FILES come back empty, which is a confusing failure mode.