Causa e solução do erro 413 Request Entity Too Large | Suporte completo para Nginx, PHP e Apache
Ao implementar a funcionalidade de upload de arquivo, você pode ver subitamente o erro 「413 Request Entity Too Large」 no navegador. Este erro é um código de status HTTP retornado quando o tamanho do corpo da solicitação enviada excede o limite definido no servidor. Este artigo abrange os locais de configuração do Nginx, PHP e Apache respectivamente, e explica sistematicamente desde a identificação até a resolução da causa.
O que é o erro 413
O código de status HTTP 413 (renomeado para 「Content Too Large」 em RFC 9110) é retornado quando o corpo da solicitação enviado pelo cliente excede o tamanho processável pelo servidor. Não é limitado apenas a uploads de arquivo; também ocorre ao enviar payloads JSON grandes ou dados codificados em Base64.
Quando esse erro ocorre, o servidor rejeita a solicitação em si, portanto a conexão é fechada antes que o processamento atinja o código do lado da aplicação (PHP, Python, etc.). Como resultado, nenhum registro permanece no log da aplicação, e você precisa verificar o log de erros do servidor Web.
Nginx: Configuração de client_max_body_size
Por padrão, o Nginx tem <code>client_max_body_size</code> definido como <strong>1MB</strong>. Para sites que aceitam uploads de imagens ou PDFs, é quase certo que esse valor precisará ser aumentado.
# /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;
}
}
}
A ordem de prioridade das configurações é <code>location</code> > <code>server</code> > <code>http</code>. Se você deseja aumentar o limite apenas para um endpoint de upload específico, é uma prática recomendada especificá-lo no bloco <code>location</code>.
# 設定変更後は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: relação entre upload_max_filesize / post_max_size / memory_limit
PHP tem múltiplas limitações de tamanho e você precisa compreender corretamente a relação entre elas. Configure sempre para satisfazer a seguinte desigualdade.
; 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
| Diretiva | Valor padrão | Escopo de impacto |
|---|---|---|
upload_max_filesize |
2M | Tamanho máximo de 1 arquivo |
post_max_size |
8M | Solicitação POST completa (arquivo + dados de formulário) |
memory_limit |
128M | Uso máximo de memória durante a execução do script |
max_file_uploads |
20 | Número de arquivos que podem ser carregados simultaneamente |
max_execution_time |
30 | Número máximo de segundos para execução do script (arquivos grandes precisam de extensão) |
max_input_time |
60 | Número máximo de segundos para análise de dados 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: Configuração de LimitRequestBody
No Apache, você define o limite do corpo da solicitação com a diretiva <code>LimitRequestBody</code>. O padrão é 0 (ilimitado), mas é recomendado definir um limite apropriado por questões de segurança.
# /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
Erros comuns de combinação
O aspecto problemático do erro 413 é que existem limites definidos em múltiplas camadas. Frequentemente, mesmo alterando uma configuração, a requisição é bloqueada em outra camada.
Caso 1: Nginx passa, mas é rejeitado no PHP
Se o <code>client_max_body_size</code> do Nginx estiver configurado para 100m, mas o <code>upload_max_filesize</code> do PHP permanecer em 2M, um arquivo de 50MB passará pelo Nginx, mas será ignorado pelo PHP. Nesse caso, o HTTP retornará status 200, mas o arquivo ficará vazio e <code>$_FILES</code> terá o código de erro 1 (UPLOAD_ERR_INI_SIZE) definido.
Caso 2: upload_max_filesize é suficiente, mas post_max_size não é
Mesmo que você defina <code>upload_max_filesize = 50M</code>, se <code>post_max_size = 8M</code> permanecer, toda a solicitação que exceder 8MB será descartada. Neste caso, <code>$_POST</code> e <code>$_FILES</code> se tornam arrays vazios, o que é um comportamento confuso.
Caso 3: Negligência na configuração de proxy reverso
Ao usar Nginx como proxy reverso com Apache + PHP-FPM no backend, você precisa definir os limites em Nginx, Apache e 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;
}
}
Procedimento de depuração
Quando ocorre um erro 413, identifique a causa seguindo os passos abaixo.
# 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 teste
Após alterar a configuração, é importante fazer testes carregando arquivos de diferentes tamanhos. O DevLab fornece arquivos para testes de valores limites. Teste antes e depois do limite máximo (exemplo: se o limite for 50MB, teste com 49MB, 50MB e 51MB) e confirme se o comportamento está conforme 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>
Resumo das configurações recomendadas para cada servidor
| Camada | Diretiva | Valor recomendado (compatível com upload de 50MB) |
|---|---|---|
| Nginx | client_max_body_size |
60m (com margem) |
| PHP | upload_max_filesize |
50M |
| PHP | post_max_size |
55M (maior que <code>upload_max_filesize</code>) |
| PHP | memory_limit |
256M |
| Apache | LimitRequestBody |
62914560 (60MB, em bytes) |
Arquivo de teste disponível para usar neste artigo (gratuito)
- → <a href="/ja/files/threshold/png/10mb/" class="text-primary-600 dark:text-primary-400 hover:underline">PNG teste de valores limite 10MB</a> — Para teste com arquivo acima do limite padrão do Nginx (1MB)
- → <a href="/ja/files/threshold/png/50mb/" class="text-primary-600 dark:text-primary-400 hover:underline">PNG teste de valores limite 50MB</a> — Para teste do limite upload_max_filesize
- → <a href="/ja/files/threshold/" class="text-primary-600 dark:text-primary-400 hover:underline">Lista de arquivos de teste de valores limite</a> — Arquivos de teste de valores limite de vários tamanhos
- → <a href="/ja/files/images/png/1mb/" class="text-primary-600 dark:text-primary-400 hover:underline">Imagem PNG de teste 1MB</a> — Para verificação de operação em tamanho pequeno
Artigos relacionados
- → <a href="/ja/blog/nginx-upload-config/" class="text-primary-600 dark:text-primary-400 hover:underline">Guia de Configuração de Upload de Arquivos Nginx | client_max_body_size e configuração proxy</a>
- → <a href="/ja/blog/file-validation-checklist/" class="text-primary-600 dark:text-primary-400 hover:underline">Lista de verificação de implementação de validação de arquivo para formulários web</a>
- → <a href="/ja/blog/http-422-error/" class="text-primary-600 dark:text-primary-400 hover:underline">Causas e soluções do erro 422 Unprocessable Entity</a>
- → <a href="/ja/blog/http-507-error/" class="text-primary-600 dark:text-primary-400 hover:underline">Causas e soluções do erro 507 Insufficient Storage</a>