本文へスキップ

Create 入りクライアントがバニラ系サーバーで切断される原因は「地図パケット」だった

MinecraftCreateForgeトラブルシューティング

Minecraft サーバー で起きた、Create 入りクライアントがロビーで切断される障害の記録です。 原因にたどり着くまでかなり遠回りしたので、同じところでハマった誰か(と、未来の自分)のために残しておきます。

症状

2026年9月3日の夜から、Mod サーバーに入ろうとすると途中で切断される人が出始めました。 サーバー構成は Velocity の下に、バニラ系の Hub(Purpur)と Forge 1.20.1 の Mod サーバーがぶら下がる形です。

クライアント側のエラーはこれ。

DecoderException: IndexOutOfBoundsException:
  readerIndex(16398) + length(1) exceeds writerIndex(16398)

遠回りしたところ

最初は Velocity、Ambassador、ViaVersion、NPC プラグイン、Fallback 系プラグイン、announce-forge 設定……と、それっぽいところを片っ端から疑いました。全部ハズレです。

特に罠だったのが、ログに出てくるこれ。

Received invalid discriminator byte 98 on channel fml:handshake

いかにも原因っぽい見た目ですが、接続に成功したときにも出る無害なログでした。これを追いかけて時間を溶かしました。

原因

決め手になったのはエラーの数字です。16398 = 128×128(地図の色データ 16384)+ ヘッダー 14 バイト。つまり「地図のパケット」です。

Create 6.0.8 は mixin(ClientboundMapItemDataPacketMixin)で、地図パケットに駅マーカー用のデータを足しています。この mixin は common 側なので、クライアントの読み込み処理にも効きます。 その結果、Create 入りクライアントがバニラ系サーバー(今回は Hub)から満杯の地図パケットを受け取ると、「Create 用の追加データ」を1バイト余分に読もうとして落ちる、という仕組みでした。

地図を送っていたのは Hub の ImageFrame(地図に画像を貼るプラグイン)でした。

対処

Create の jar の中の create.mixins.json から、該当 mixin の1行を削除した私家版を作って、クライアントと Forge サーバーの両方に配りました。

  • 片側だけ入れ替えると、今度は逆向きに壊れます。
  • 失うのは「地図に駅マーカーが出る」機能だけです。
  • コンフィグの showTrainMapOverlay = false では直りません。mixin はクラスを読み込んだ時点で適用されるからです。
  • Create を更新するたびに同じパッチを当て直す必要があります。

教訓

  • エラーに出てくる数字は計算してみる。16398 が地図のサイズだと気づいた瞬間に一気に進みました。
  • Mod の切り分けは、素の Forge 1.20.1 に Mod ゼロから足していく二分探索が一番速いです。
  • DecoderException はクライアントのログ(latest.log)には残りません。Loaded N advancements まで到達したかどうかで生死を判定しました。
  • 「それっぽいエラーログ」が本当に失敗時だけ出るのかは、成功時のログと見比べて確かめる。

サーバー側ではなく、Mod が手を入れたクライアント側でパケットの読み方が変わっていた、というのが今回のオチでした。