Error 413 Request Entity Too Large: causas y soluciones | Soporte completo para Nginx, PHP y Apache
Al implementar la funcionalidad de carga de archivos, puede ver repentinamente un error "413 Request Entity Too Large" en el navegador. Este código de estado HTTP se devuelve cuando el tamaño del cuerpo de la solicitud enviada excede el límite configurado del servidor. Este artículo cubre exhaustivamente las ubicaciones de configuración para Nginx, PHP y Apache, explicando sistemáticamente cómo identificar la causa y resolver el problema.
¿Qué es un error 413?
El código de estado HTTP 413 (renombrado a "Content Too Large" en RFC 9110) se devuelve cuando el cuerpo de solicitud enviado por el cliente excede el tamaño máximo procesable del servidor. Esto ocurre no solo para cargas de archivos, sino también para transmisión de grandes cargas JSON o datos codificados en Base64.
Cuando ocurre este error, el servidor rechaza la solicitud en sí, por lo que la conexión se cierra antes de que el procesamiento llegue al código de la aplicación (PHP, Python, etc.). Como resultado, no queda registro en el registro de aplicación y debe verificar el registro de errores del servidor web.
Nginx: Configuración de client_max_body_size
Por defecto, Nginx tiene <code>client_max_body_size</code> establecido en <strong>1MB</strong>. Para sitios que aceptan carga de imágenes o PDF, casi con seguridad necesitará aumentar este valor.
# /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;
}
}
}
El orden de prioridad de los ajustes es <code>location</code> > <code>server</code> > <code>http</code>. Si desea aumentar el límite solo para un endpoint de carga específico, especificarlo en el bloque <code>location</code> es una mejor práctica.
# 設定変更後は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: Relación entre upload_max_filesize / post_max_size / memory_limit
PHP tiene múltiples límites de tamaño y debe comprender correctamente la relación entre ellos. Siempre configure para satisfacer la siguiente desigualdad.
; 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
| Directiva | Valor predeterminado | Alcance del impacto |
|---|---|---|
upload_max_filesize |
2M | Tamaño máximo de archivo |
post_max_size |
8M | Solicitud POST completa (archivo + datos de formulario) |
memory_limit |
128M | Uso máximo de memoria durante la ejecución del script |
max_file_uploads |
20 | Número de archivos que se pueden cargar simultáneamente |
max_execution_time |
30 | Número máximo de segundos para la ejecución del script (se requiere extensión para archivos grandes) |
max_input_time |
60 | Máximo de segundos permitidos para analizar datos de entrada |
// 現在の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: Configuración de LimitRequestBody
En Apache, use la directiva <code>LimitRequestBody</code> para establecer un límite en el cuerpo de la solicitud. El valor predeterminado es 0 (ilimitado), pero se recomienda establecer un límite apropiado por seguridad.
# /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
Errores comunes de combinación
Lo complicado del error 413 es que hay múltiples capas, cada una con sus propios límites de tamaño. Incluso si cambias una configuración, las solicitudes se bloquean frecuentemente en otra capa.
Caso 1: Pasa a través de Nginx pero es rechazado por PHP
Si <code>client_max_body_size</code> de Nginx se establece en 100m pero PHP's <code>upload_max_filesize</code> permanece en 2M, un archivo de 50MB pasará por Nginx pero será ignorado por PHP. En este caso, el estado HTTP devolverá 200, pero el archivo estará vacío y <code>$_FILES</code> contendrá el código de error 1 (UPLOAD_ERR_INI_SIZE).
Caso 2: upload_max_filesize es suficiente pero post_max_size no lo es
Aunque configure <code>upload_max_filesize = 50M</code>, si <code>post_max_size = 8M</code> permanece sin cambios, cualquier solicitud que supere 8MB se descartará por completo. En este caso, tanto <code>$_POST</code> como <code>$_FILES</code> se convierten en matrices vacías, lo que es un comportamiento confuso.
Caso 3: Supervisión en la configuración de proxy inverso
Cuando usa Nginx como proxy inverso con Apache + PHP-FPM en el backend, debe establecer límites en los tres: Nginx, Apache y 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;
}
}
Procedimiento de depuración
Cuando ocurre un error 413, identifique la causa utilizando los siguientes pasos.
# 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
Método de prueba
Después de cambiar la configuración, es importante probar cargando archivos de diferentes tamaños. DevLab proporciona archivos para pruebas de valores límite. Pruebe alrededor del límite superior (por ejemplo, si el límite es 50MB, pruebe con 49MB, 50MB y 51MB) y verifique que el comportamiento sea el esperado.
# 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>
Resumen de configuración recomendada para cada servidor
| Capa | Directiva | Valor Recomendado (soporta cargas de 50MB) |
|---|---|---|
| Nginx | client_max_body_size |
60m (con algo de margen) |
| PHP | upload_max_filesize |
50M |
| PHP | post_max_size |
55M (mayor que <code>upload_max_filesize</code>) |
| PHP | memory_limit |
256M |
| Apache | LimitRequestBody |
62914560 (60 MB, en bytes) |
Archivos de prueba para este artículo (gratis)
- → <a href="/ja/files/threshold/png/10mb/" class="text-primary-600 dark:text-primary-400 hover:underline">PNG de prueba de valores límite 10MB</a> — Prueba de exceso del límite predeterminado de Nginx (1MB)
- → <a href="/ja/files/threshold/png/50mb/" class="text-primary-600 dark:text-primary-400 hover:underline">PNG de prueba de valores límite 50MB</a> — Prueba del límite upload_max_filesize
- → <a href="/ja/files/threshold/" class="text-primary-600 dark:text-primary-400 hover:underline">Lista de archivos de prueba de valores límite</a> — Archivos de prueba de valores límite de varios tamaños
- → <a href="/ja/files/images/png/1mb/" class="text-primary-600 dark:text-primary-400 hover:underline">Imagen PNG de Prueba 1MB</a> — Para verificar el comportamiento con tamaños pequeños
Artículos relacionados
- → <a href="/ja/blog/nginx-upload-config/" class="text-primary-600 dark:text-primary-400 hover:underline">Guía de Configuración de Carga de Archivos en Nginx | client_max_body_size, Configuración Proxy</a>
- → <a href="/ja/blog/file-validation-checklist/" class="text-primary-600 dark:text-primary-400 hover:underline">Lista de Verificación de Implementación de Validación de Archivos en Formularios Web</a>
- → <a href="/ja/blog/http-422-error/" class="text-primary-600 dark:text-primary-400 hover:underline">Error 422 Unprocessable Entity: Causas y Soluciones</a>
- → <a href="/ja/blog/http-507-error/" class="text-primary-600 dark:text-primary-400 hover:underline">Error 507 Insufficient Storage: Causas y Soluciones</a>