Skip to content

Causa e solução do erro 413 Request Entity Too Large | Suporte completo para Nginx, PHP e Apache

Categoria:Servidor · HTTP
Este artigo está disponível atualmente apenas em japonês. As versões traduzidas serão publicadas sequencialmente.

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>