【解決】.NET MAUI AndroidのInvalid dex file indices(classes2.dex)原因と地域設定(数字形式)の直し方

.NET MAUIでAndroidアプリをReleaseでpublishすると、bundletoolが「Invalid dex file indices…classes2.dexが見つかる」として失敗することがあります。Xamarin時代のkeystoreを流用して署名設定を追加した直後に出やすい現象で、原因はコードではなくWindowsの地域設定(数字の形式)にあるケースが多いです。ここでは再現条件の整理から、最短で直す手順、再発防止までをまとめます。

目次

発生するエラーと典型的な状況

次のように dotnet publish でAndroid向けに発行(公開)しようとしたタイミングで失敗します。Debugビルドでは通るのに、Release publishでだけ落ちる、というパターンが代表的です。

dotnet publish -c Release -f net6.0-android

ログには以下のようなメッセージが出ます(環境により前後は多少異なります)。

[BT : 1.8.1] error : Invalid dex file indices, expecting file 'classes?.dex' but found 'classes2.dex'
項目内容
発生タイミングReleaseでpublish(特にAAB生成や署名処理が走る工程)
対象.NET MAUI(Android)/net6.0-android など
よくある前提Xamarin時代に作ったkeystoreを流用し、csprojに署名設定(<AndroidKeyStore>True</AndroidKeyStore>等)を追加
症状「classes?.dex を期待したが classes2.dex が見つかった」とdexファイル名の整合性で弾かれる

なぜkeystore設定後に起きやすいのか

結論から言うと、keystoreそのものが壊れているわけではありません。署名設定を入れると、publish時に「署名付きの成果物を作る」ための工程が増え、結果として AAB(Android App Bundle)の作成やbundletoolによる検証 が確実に走るようになります。この検証工程でdexファイルの並び・命名(classes.dex, classes2.dex, classes3.dex…)が厳密にチェックされ、そこで初めて問題が表面化します。

よくある現象は次のとおりです。

  • Debug(APK中心)では通る
  • Release publish(AAB+署名+検証)で落ちる

つまり「署名を入れたから壊れた」ではなく、「署名を入れたことで、厳密な検証を通るルートに入った」という見方が正確です。

前提知識:dexファイル名のルール(classes.dex / classes2.dex)

Androidでは、コンパイル結果のバイトコードが .dex(Dalvik Executable)としてパッケージに入ります。アプリ規模が大きいとdexが複数に分かれ(いわゆるマルチdex)、次の命名規則になります。

dex番号期待されるファイル名補足
1つ目classes.dex最初は数字が付かない(classes1.dex ではない)
2つ目classes2.dexここから数字が付く
3つ目以降classes3.dex…連番で続く

bundletoolはこの連番が正しいか、ファイル名が正しいかをチェックします。したがって「数字の文字が別物」になると、連番として認識できずに失敗します。

原因:classes?.dex の「?」は“数字の文字化け”であることが多い

このエラーの核心は、dexのインデックス番号部分がASCIIの「0〜9」になっていない 可能性が高いことです。

本来、2つ目のdexは classes2.dex という ASCIIの「2」 を含むファイル名になるはずです。しかし、Windowsの言語/地域設定(とくに数字の表示形式)が影響して、ビルド工程のどこかで数字がロケール依存の文字になり、結果として「見た目は2に見えるが別文字」という状態を作ります。

たとえば、数字の“表記”には次のようなバリエーションがあります。

見た目文字の例よくある由来ASCIIの2と同一?
22英語(US)などの通常設定はい
2全角2(U+FF12)全角数字が混ざる環境、コピー&ペーストなどいいえ
٢アラビア・インド数字の2(例)アラビア系ロケール、ネイティブ数字設定いいえ
२デーヴァナーガリー数字の2(例)ヒンディー語系ロケール等いいえ

ログ上は「classes?.dex」のように ? に見えますが、これは「本当は何らかの別文字なのに、ログ出力の文字コードや表示環境の都合で ? になっている」ケースが典型です。結果としてツール側は「期待している dex 名」と「実際にある dex 名」が一致しないと判断し、Invalid dex file indices で停止します。

「dexが多すぎる」問題と混同しない

Androidのビルドエラーには「メソッド数が多すぎてdexが分割される」「マルチdex設定が必要」といった別系統の話もあります。しかし今回のエラーは、dexの“数”そのものではなく、dexファイル名の整合性(インデックス)で落ちています。混同すると遠回りになります。

よくある別エラー原因の方向性今回(Invalid dex file indices)との違い
65K制限やMultiDex関連参照メソッド数、分割設定、R8/ProGuard「dexが作れない/入りきらない」の話で、ファイル名の文字化けとは別
署名失敗(keystore/パスワード)証明書・エイリアス・パスワードの不一致署名工程の失敗で、dexインデックスの検証エラーではない
Android SDK/Build Tools不足SDKパス、ビルドツールの欠落環境構築エラーで、特定のファイル名を期待する系とは挙動が違う

対処:Windowsの地域設定(数値形式)を英語の0-9に揃える

回避策として最も効果が高いのは、Windowsの「地域/形式/数字」設定を英語(例:English (United States))相当にする ことです。ポイントは「表示言語」だけではなく、地域設定の“数字の形式が0-9(半角)になっていること” です。

設定箇所推奨理由
地域の形式(Regional format)English (United States) など数値のフォーマットが英語の0-9になりやすい
ネイティブ数字(Use native digits)無効/使わない(Never)ロケール依存の数字(別文字)を避けられる
システムロケール(非Unicodeプログラムの言語)必要なら英語に古いツールや一部の工程が影響を受ける場合がある

Windows 11での変更手順(例)

  1. 「設定」→「時刻と言語」→「言語と地域」を開く
  2. 「地域」または「地域の形式(Regional format)」を English (United States) などに変更
  3. 「関連設定」から「管理用の言語設定」やコントロールパネルの「地域」を開ける場合は、追加設定(形式) で数字(ネイティブ数字)の扱いを確認
  4. 変更後、サインアウト/再起動を挟む(反映が曖昧な場合の保険)

Windows 10での変更手順(例)

  1. 「設定」→「時刻と言語」→「地域」を開く
  2. 「地域設定」や「地域の形式」を English (United States) に変更
  3. 「関連設定」→「日付、時刻、または数値形式の変更」(コントロールパネルの「地域」)を開き、形式/数字の設定を確認

数字がASCIIかどうかを確認する(PowerShell)

UIでの設定変更が難しい場合や、変更しても直らない場合は「今のカルチャで0〜9がどう扱われているか」を先に確認すると切り分けが早くなります。

$c = Get-Culture
$c.Name
$c.NumberFormat.NativeDigits
$c.NumberFormat.DigitSubstitution

NativeDigits に 0 1 2 3 4 5 6 7 8 9 以外の文字が出る場合は要注意です(見た目が似ていても別文字の可能性があります)。

重要なのは「英語表示にすること」ではなく、数字が0-9として扱われる状態にすることです。見た目が同じ“2”でも、内部的に別文字だとファイル名としては一致しません。

やり直し手順:Clean → Rebuild → publish(生成物を残さない)

設定変更後にそのままpublishし直しても、途中生成物(obj や bin)に“問題のある命名”が残っていると再発しやすくなります。次の手順で一度まっさらにしてから再実行するのが安全です。

dotnetコマンドでクリーンする

dotnet clean -c Release -f net6.0-android
dotnet publish -c Release -f net6.0-android

フォルダごと削除して完全に作り直す(推奨)

プロジェクト直下で bin と obj を削除してからpublishします。

rmdir /s /q bin
rmdir /s /q obj
dotnet publish -c Release -f net6.0-android

Visual Studioで作業している場合も、

  • 「ビルド」→「ソリューションのクリーン」
  • 「ビルド」→「ソリューションのリビルド」
  • その後にpublish

の順に進めると、古い生成物による取りこぼしが減ります。

直ったかを確認する方法(dexファイル名を目で見る)

原因が「数字の文字」なので、成果物の中身を確認すると納得感が高まります。AABが生成できるところまで進む場合は、AABの中にあるdex名を見てください。

AABを展開して確認する

  1. publish後に生成された .aab を探す(例:bin\Release\net6.0-android\publish\ 配下)
  2. .aab はzipなので、7-Zip等で開く
  3. base/dex/ 付近に classes.dex, classes2.dex… が並ぶか確認

コマンドで見るなら、JDKが入っている環境では次のように一覧化できます(Windowsならfindstrで絞り込み)。

jar tf YourApp.aab | findstr /i dex
jar tf YourApp.aab | findstr /i classes

もし classes2.dex のような全角数字や、見慣れない数字が混ざっていたら、まさにこの問題のパターンです。地域設定を英語の0-9に揃えてクリーンビルドすると、classes2.dex のようにASCII数字に統一されます。

言語を英語にしたのに直らないときのチェックリスト

「Windowsの表示言語を英語にしたのに直らない」という場合、表示言語ではなく“地域の形式”や“数字設定”が残っていることが多いです。次の順で潰すと切り分けが早いです。

チェック項目確認ポイント対処の方向性
地域の形式Regional format が英語(US等)になっているか「地域」設定を変更
ネイティブ数字数字がローカル表記になっていないか「ネイティブ数字を使わない(Never)」に寄せる
システムロケール非Unicodeプログラムの言語が影響していないか管理用設定で英語に変更(必要に応じて)
古い生成物bin/objが残っていないかbin/obj削除→再publish
複数環境の混在同じブランチを別PCでビルドして成果物を流用していないかpublish環境を固定し、成果物の出所を統一

また、ログ上の ? は“表示の問題”でもあるため、コンソールの文字コードをUTF-8にしても見た目は改善する可能性があります。しかし本件は「ファイル名の一致判定」で落ちているため、表示を直すだけでは根本解決にならない点に注意してください。

署名設定(csproj)の例と注意点

keystore流用自体は一般的な運用です。設定はプロジェクトにより異なりますが、イメージしやすいように典型例を載せます(パスやパスワードは環境に合わせてください)。

&lt;PropertyGroup&gt;
  &lt;AndroidKeyStore&gt;True&lt;/AndroidKeyStore&gt;
  &lt;AndroidSigningKeyStore&gt;YourKeyStore.keystore&lt;/AndroidSigningKeyStore&gt;
  &lt;AndroidSigningStorePass&gt;******&lt;/AndroidSigningStorePass&gt;
  &lt;AndroidSigningKeyAlias&gt;your_alias&lt;/AndroidSigningKeyAlias&gt;
  &lt;AndroidSigningKeyPass&gt;******&lt;/AndroidSigningKeyPass&gt;
&lt;/PropertyGroup&gt;

この設定を入れたからエラーが起きるのではなく、「署名ありpublishの工程で問題が顕在化する」だけです。署名設定を外して回避するのは一時的な切り分けには有効ですが、最終的には地域設定(数字)を直して、署名ありpublishが通る状態に戻すのが本筋です。

再発防止:チーム開発・CIでハマらないための運用

この手のロケール依存バグは、個人PCの設定差で突然発生し、原因に辿り着きにくいのが厄介です。再発防止として、次の運用をおすすめします。

  • publish担当マシン(またはCI)を固定し、地域設定(数字形式)を明文化する
  • リリース時は必ず bin/obj削除→publish を手順に含める
  • 「突然通らなくなった」時に備え、エラー文(Invalid dex file indices / classes?.dex) をチームのナレッジに残す
  • 可能なら CIで署名付きAABを生成し、ローカル依存を減らす(Azure DevOps/GitHub Actions等)

特にCIは、実行環境のカルチャが安定しやすく、個人の地域設定に引きずられません。ローカルでの再現が難しい場合でも、CIで成功しているなら「環境差(ロケール差)」が疑いどころになります。

まとめ

  • Invalid dex file indices で classes?.dex と出る場合、「?」は数字の文字化けである可能性が高い
  • 表示言語だけでなく、地域設定の数値形式(0-9のASCII数字) を揃えるのが重要
  • 設定変更後は bin/obj削除(クリーン)→Rebuild→publish を徹底する
  • 成果物(AAB)を展開して classes2.dex の“2”がASCIIになっているか確認すると確実

コードをいくら見直しても直らないタイプのエラーなので、環境(特に数字の形式)を疑うのが最短ルートです。同じ症状で詰まっている場合は、まず地域設定を見直し、クリーンからやり直してみてください。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次