ファイルアップロード時のエラー原因と対処
(Spring Boot 3.3+ / embedded Tomcat / 検証結果を踏まえた客先向け資料)
1. 結論(要点)
- 発生した例外の正体:
FileCountLimitExceededException(multipart の “part” 数上限超過) - Spring Boot 3.3+ の実効デフォルト:
server.tomcat.max-part-count=10 - そのため 11 個以上の part を含むリクエストは拒否された
- 解決策:
server.tomcat.max-part-count=30に設定(今回の画面では最大 15〜18 part → 30 で余裕)
2. 検証で確認できた事実
- **テキストのみ(約100項目)**の画面
- 送信形式:
application/x-www-form-urlencoded - part 制限の対象外 → 正常動作
- 送信形式:
- **ファイルアップロードあり(テキスト 3〜5)**の画面
- 送信形式:
multipart/form-data -
server.tomcat.max-part-count=10→ エラー発生(上限超過) -
server.tomcat.max-part-count=11→ 単一ファイル時は解消(ただし最大想定時は不足) - ログで
FileCountLimitExceededExceptionを観測
- 送信形式:
3. 技術的背景:multipart と「part」の数え方
-
multipart/form-dataのとき、Tomcat は すべての入力要素を part としてカウントします。 - カウント対象:
- アップロードファイル → 1ファイルにつき 1 part
-
input type="text"→ 1項目につき 1 part -
input type="hidden"→ 1項目につき 1 part - CSRF トークン等の hidden フィールド → 1 part
総 part 数 = ファイル数 + テキスト数 + hidden/CSRF 数
これがserver.tomcat.max-part-countを超えると Tomcat が解析を拒否し、FileCountLimitExceededExceptionが発生します。
4. 今回の画面の必要 part 数
- 最大ファイル数:10
- テキスト入力:3〜5
- hidden / CSRF:2〜3
合計:約 15〜18 part
5. デフォルト値の違い(誤解しがちな点)
-
Tomcat 本体のデフォルト:
maxPartCount = 1000(十分余裕あり) -
Spring Boot 3.3+ の実効値:
server.tomcat.max-part-count = 10 - 今回は Spring Boot 側の制限に該当し、
FileCountLimitExceededExceptionが発生
6. 実際に観測されたエラー例
- 例外名:
FileCountLimitExceededException - 表層メッセージ例:
Failed to parse multipart servlet requestToo many partsmaxPartCount exceeded
7. 推奨設定と導入手順
- application.properties への設定
server.tomcat.max-part-count=30
-
理由
- 想定必要 part:15〜18
- 安全係数を考慮して 30 に設定(想定最大の約 2 倍)
- 将来、最大ファイル数を増やす場合は最大ケース+余裕で再調整(例:最大20ファイル → 40〜60)
-
導入手順
- 上記設定を
application.propertiesに追加 - アプリケーションを再起動
- 対象画面で 最大ケース(ファイル10+入力あり) を実機検証
- ログ/メトリクスで挙動を監視
- 上記設定を
8. 実装・環境チェックリスト(再発防止)
-
フォーム送信
-
<form enctype="multipart/form-data">を指定 -
input type="file"のnameをサーバ側(フォームモデル/@RequestParam)と一致させる
-
-
Ajax(jQuery)
-
FormDataを使用 -
processData: falseとcontentType: falseを指定
-
-
Spring 設定
spring.servlet.multipart.enabled=true-
spring.servlet.multipart.max-file-size/spring.servlet.multipart.max-request-sizeを要件に合わせる -
server.tomcat.max-part-countを要件+余裕で設定(本件は 30)
-
その他
- フィルタ/Interceptor が事前にリクエストボディを読み取っていないことを確認
- 変更後はログ/APM で multipart 関連のエラー増加を監視
9. 運用・セキュリティ注意
- 値を大きくしすぎると DoS(大量 part 投げ込み) に弱くなるため、無制限は避ける
- 原則:想定最大値+余裕(2〜3倍) で設定
- WAF/レート制御/ログ監視で不正リクエストを検知
10. まとめ
- 問題の本質:multipart の part 数制限 による
FileCountLimitExceededException - Spring Boot 3.3+ 実効デフォルト 10 によって 11 以上のリクエストが拒否されていた
- 本画面は最大 15〜18 part 必要 →
server.tomcat.max-part-count=30で解消・安定運用可能