1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

spring-boot 3.5.3のバグについて

Last updated at Posted at 2025-09-19

ファイルアップロード時のエラー原因と対処

(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 request
    • Too many parts
    • maxPartCount exceeded

7. 推奨設定と導入手順

  • application.properties への設定
server.tomcat.max-part-count=30
  • 理由

    • 想定必要 part:15〜18
    • 安全係数を考慮して 30 に設定(想定最大の約 2 倍)
    • 将来、最大ファイル数を増やす場合は最大ケース+余裕で再調整(例:最大20ファイル → 40〜60)
  • 導入手順

    1. 上記設定を application.properties に追加
    2. アプリケーションを再起動
    3. 対象画面で 最大ケース(ファイル10+入力あり) を実機検証
    4. ログ/メトリクスで挙動を監視

8. 実装・環境チェックリスト(再発防止)

  • フォーム送信
    • <form enctype="multipart/form-data"> を指定
    • input type="file"name をサーバ側(フォームモデル/@RequestParam)と一致させる
  • Ajax(jQuery)
    • FormData を使用
    • processData: falsecontentType: 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 で解消・安定運用可能
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?