413 Request Entity Too Large error: causes and solutions | Complete guide for Nginx, PHP, and Apache
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 <code>client_max_body_size</code> set to <strong>1MB</strong>. 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 <code>location</code> > <code>server</code> > <code>http</code>. If you want to increase the limit for only a specific upload endpoint, specifying it in the <code>location</code> 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 <code>LimitRequestBody</code> 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 <code>client_max_body_size</code> is set to 100m but PHP's <code>upload_max_filesize</code> 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 <code>$_FILES</code> 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 <code>upload_max_filesize = 50M</code>, if <code>post_max_size = 8M</code> remains unchanged, any request exceeding 8MB will be entirely discarded. In this case, both <code>$_POST</code> and <code>$_FILES</code> 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 <code>upload_max_filesize</code>) |
| PHP | memory_limit |
256M |
| Apache | LimitRequestBody |
62914560 (60 MB, in bytes) |
Test files for this article (free)
- → <a href="/ja/files/threshold/png/10mb/" class="text-primary-600 dark:text-primary-400 hover:underline">10MB boundary value test PNG</a> — Test exceeding Nginx default limit (1MB)
- → <a href="/ja/files/threshold/png/50mb/" class="text-primary-600 dark:text-primary-400 hover:underline">50MB boundary value test PNG</a> — Test upload_max_filesize limit
- → <a href="/ja/files/threshold/" class="text-primary-600 dark:text-primary-400 hover:underline">Boundary Value Test Files</a> — Boundary value test files of various sizes
- → <a href="/ja/files/images/png/1mb/" class="text-primary-600 dark:text-primary-400 hover:underline">1MB Test PNG Image</a> — For verifying behavior with small sizes
Related articles
- → <a href="/ja/blog/nginx-upload-config/" class="text-primary-600 dark:text-primary-400 hover:underline">Nginx File Upload Configuration Guide | client_max_body_size, Proxy Settings</a>
- → <a href="/ja/blog/file-validation-checklist/" class="text-primary-600 dark:text-primary-400 hover:underline">Web Form File Validation Implementation Checklist</a>
- → <a href="/ja/blog/http-422-error/" class="text-primary-600 dark:text-primary-400 hover:underline">422 Unprocessable Entity Error: Causes and Solutions</a>
- → <a href="/ja/blog/http-507-error/" class="text-primary-600 dark:text-primary-400 hover:underline">507 Insufficient Storage Error: Causes and Troubleshooting</a>