タイトル: PostTooLargeException
SEOタイトル: Laravel PostTooLargeException の原因と対処完全ガイド
| この記事の要点 |
|
エラーの全体像
Illuminate\Http\Exceptions\PostTooLargeException
The POST data is too large.
at vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php
HTTP Status: 413 Payload Too Large
Laravel の ValidatePostSize ミドルウェアがリクエストサイズと post_max_size を比較し、超えていれば即座にこの例外を投げます。$_POST や $_FILES が空になるのを未然に検知する仕組みです。
原因の切り分け
| 確認 | 方法 | 該当時の対処 |
|---|---|---|
| php.ini の値 | php -i | grep post_max_size | 対処1 |
| php-fpm 用の ini を編集したか | php --ini でロードされる ini を確認 | 対処1(FPM 用) |
| Nginx の上限 | nginx -T | grep client_max_body_size | 対処2 |
| Apache の上限 | httpd -M | grep limit | 対処2 |
| サービス再起動したか | systemctl status php8.3-fpm | 再起動 |
対処1: php.ini を編集
; /etc/php/8.3/fpm/php.ini (Laravel の本番では FPM 用)
; /etc/php/8.3/cli/php.ini (CLI 用、artisan 用)
; 1 ファイルあたり最大サイズ
upload_max_filesize = 50M
; POST 全体のサイズ上限(複数ファイル+他フィールド合計)
; ★ upload_max_filesize より大きく設定
post_max_size = 60M
; メモリ上限(画像処理する場合大きめに)
memory_limit = 512M
; 同時に送れるファイル数
max_file_uploads = 20
; アップロード時間
max_execution_time = 300
max_input_time = 300
編集後の反映:
# php-fpm を再起動
sudo systemctl restart php8.3-fpm
# Apache の mod_php なら Apache を再起動
sudo systemctl restart apache2
# 反映確認
php -i | grep -E "post_max_size|upload_max_filesize"
# 本番 FPM 経由なら phpinfo() を吐く一時 PHP を作って確認:
#
対処2: Nginx の client_max_body_size
Nginx はPHP より先にリクエストサイズを判定して 413 を返します。php.ini だけ上げても Nginx で弾かれるので両方必須:
# /etc/nginx/nginx.conf (http コンテキスト)
http {
client_max_body_size 60M;
}
# または特定 server / location だけ
server {
listen 80;
server_name example.com;
client_max_body_size 60M; # ← サーバ全体
location /api/upload {
client_max_body_size 200M; # ← このパスだけ大きめ
}
}# 構文チェック → 反映
sudo nginx -t
sudo systemctl reload nginx
対処3: Apache の LimitRequestBody
# .htaccess または httpd.conf
LimitRequestBody 62914560 # 60MB (バイト単位)
# 特定パスだけ大きく
LimitRequestBody 209715200 # 200MB
# mod_php の場合、ini 値も .htaccess で上書き可
php_value upload_max_filesize 50M
php_value post_max_size 60M
php_value memory_limit 512M
対処4: Laravel ミドルウェアでより親切なメッセージ
標準では 413 + 例外画面ですが、ハンドラでカスタマイズできます:
// app/Exceptions/Handler.php (Laravel 10 以前)
use Illuminate\Http\Exceptions\PostTooLargeException;
public function register(): void
{
$this->renderable(function (PostTooLargeException $e, $request) {
if ($request->expectsJson()) {
return response()->json([
'message' => 'アップロードサイズが大きすぎます (上限 60MB)',
'code' => 'POST_TOO_LARGE',
], 413);
}
return response()->view('errors.413', [], 413);
});
}
// Laravel 11+ bootstrap/app.php
->withExceptions(function ($exceptions) {
$exceptions->render(function (PostTooLargeException $e, $request) {
if ($request->expectsJson()) {
return response()->json([
'message' => 'アップロードサイズが大きすぎます',
], 413);
}
return response()->view('errors.413', [], 413);
});
})
サイズ単位の注意
| 場所 | 単位 | 例 |
|---|---|---|
| php.ini | K / M / G | post_max_size = 60M |
| Nginx | k / m / g | client_max_body_size 60m; |
| Apache | バイト数(数字のみ) | LimitRequestBody 62914560 |
php-fpm の編集箇所
Laravel 本番では通常 php-fpm 経由で動きます。CLI 用 php.ini を編集しても Web 経由のアップロードには反映されません:
# CLI 用 ini の場所
php --ini
# Configuration File (php.ini) Path: /etc/php/8.3/cli
# Loaded Configuration File: /etc/php/8.3/cli/php.ini
# FPM 用は別ディレクトリ
ls /etc/php/8.3/fpm/php.ini
# FPM プール(プロセスごとの設定)も影響
ls /etc/php/8.3/fpm/pool.d/www.conf
# プールごとに ini 値を上書き可能
# /etc/php/8.3/fpm/pool.d/www.conf
# php_admin_value[post_max_size] = 100M
# php_admin_value[upload_max_filesize] = 100M
根本対策: 巨大ファイル UP の設計
| 方針 | 説明 |
|---|---|
| 画像のフロント圧縮 | browser-image-compression / Canvas で送信前にリサイズ・圧縮 |
| チャンクアップロード | tus-js-client / resumable.js で分割送信、サーバで結合 |
| S3 直 PUT | 署名付き URL を発行し、ブラウザ→S3 直接送信(API サーバを経由しない) |
| マルチパート S3 | AWS SDK の Multipart Upload で 100MB 以上を効率送信 |
| 動画は HLS / DASH 配信 | 事前にトランスコードし、HTTP で部分配信 |
S3 署名付き URL の例
use Aws\S3\S3Client;
$s3 = new S3Client(['version' => 'latest', 'region' => 'ap-northeast-1']);
$cmd = $s3->getCommand('PutObject', [
'Bucket' => 'my-bucket',
'Key' => 'uploads/' . uniqid() . '.jpg',
'ContentType' => 'image/jpeg',
]);
$presigned = (string) $s3->createPresignedRequest($cmd, '+15 minutes')->getUri();
// → このURLを返し、ブラウザから PUT すれば S3 直アップロード
// Laravel サーバを経由しないので PostTooLargeException 自体起きない
FAQ
Q: php.ini を変更したのに反映されない
A: php-fpm の再起動を忘れているケースが大半。sudo systemctl restart php8.3-fpm 必須。CLI ではなく FPM 用 ini を編集しているかも確認。
Q: 413 が出るが Laravel のスタックトレースが出ない
A: Nginx が 413 を返している(PHP まで届いていない)。Nginx の client_max_body_size を確認。
Q: アップロード途中で接続が切れる
A: Nginx の client_body_timeout / Cloudflare の 100MB 上限 / php-fpm の request_terminate_timeout を確認。