Error [Unrecognized option: -Xnoagent]

Unrecognized option: -Xnoagent の直し方(JDK 23 以降で JVM が起動しない)

FIX SUMMARY verified
Applies when
eclipse-temurin@sha256:83177670e43c17769a5402a60601545318e45e63adf634fb5022340e516cded4A legacy -X launcher option (-Xnoagent, -Xfuture, -checksource) left in JVM args; the java launcher rejects it as an unrecognized option once the JDK removes it

Verified: reproduced in eclipse-temurin@sha256:83177670e43c17769a5402a60601545318e45e63adf634fb5022340e516cded4, then the Unrecognized option: -Xnoagent signature was gone after the fix (exit 0).

デバッグ用の起動オプションを昔からそのまま持ち回っているプロジェクトが、JDK 23 で止まります。

Unrecognized option: -Xnoagent
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

main() に到達する前に止まっています。同じ形で、別のオプションでも出ます。

  • Unrecognized option: -Xnoagent(JDK 23 以降)
  • Unrecognized option: -Xfuture(JDK 24 以降)
  • Unrecognized option: -checksource / -cs / -noasyncgc(JDK 24 以降)

エラー文が Unrecognized option:Unrecognized VM option

同じ「起動できない」でも、エラー文が 2 通りあります。

Unrecognized option: -Xnoagent              (これ)
Unrecognized VM option 'UseBiasedLocking'   (別の記事の対象)

-Xnoagent を弾いているのは java コマンド(launcher)です。 JDK 23 の release note も、これを launcher のオプションとして扱っています。だからエラーに VM が付きません。いっぽう UseBiasedLocking のような -XX: フラグを弾くのは、その先の HotSpot VM で、そちらは Unrecognized VM option 'X' になります。

ただし「-X なら launcher、-XX なら VM」という規則ではありません。 -Xmx64m-X で始まりますが、VM のヒープ上限を指定するもので、JDK 25 でも問題なく起動します(実測)。接頭辞では処理層を判別できないので、この記事で扱うのは -Xnoagent とその周辺の、実際に観測したオプションだけです。

直し方

起動オプションから -Xnoagent を消します。

# 消す
-Xnoagent

-Xnoagent が無効化していたのは、JDK 1.1 時代の旧デバッグ機構sun.tools.debug / sun.tools.agent)です。-Xdebug -Xnoagent -Xrunjdwp:... という定番の並びは「旧エージェントを止めて、JVMTI/JDWP を使う」という意味でした。JVMTI のエージェントを止めるものではありません(それは -agentlib:jdwp で読み込む側です)。

OpenJDK はこのオプションを非推奨にするとき、「もう何リリースも無視されていて、何の機能も提供していない」と書いています。消しても失われる動作はありません(消して終了コード 0 で起動することは実測しました)。リモートデバッグは -agentlib:jdwp=... が担っていて、-Xnoagent とは無関係です。

JAVA_OPTSDockerfileENV、CI の設定、IDE の実行構成、起動スクリプトなど、JVM 引数を組み立てている場所を全部見てください-Xnoagent は古いデバッグ設定に紛れて残っていることが多く、-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,... という 20 年前からコピーされ続けている行がそのまま生き延びていることがあります。

予告はいつ出るか(オプションごとに違う)

-Xnoagent を各 JDK で実測した結果です。

JDK結果
17 / 21無警告で起動(rc=0
22Option -Xnoagent was deprecated in JDK 22 and will likely be removed(警告つき・rc=0
23 / 24 / 25Unrecognized option: -Xnoagent(起動拒否・rc=1

非推奨の警告が出るのは 22 の 1 版だけで、その次の 23 でもう拒否されます。17(LTS)や 21(LTS)から 23 以降へ上げると、警告の段を 1 度も見ないまま起動拒否に当たります。

予告のタイミングはオプションごとに違います。 -Xfuture は 17 の時点から Warning: -Xfuture option is deprecated and may be removed を出していて(実測)、削除は 24 です。「まとめて非推奨になり、まとめて消える」わけではないので、1 つ消したからといって残りが安全とは限りません。

-Xfuture は消すだけでなく、読み替える

-Xfuture は JDK 24 で削除され、同じ 24 で -checksource-cs-noasyncgc も消えています(実測。17〜23 では警告つきで rc=0、24 以降は Unrecognized optionrc=1)。-Xfuture を消して再起動したら -checksource で止まった、という踏み方をします。

ただし -Xfuture だけは、単に消すと機能が失われます。 これは厳密なクラスファイル検証を有効にするオプションで、実際に働いていました。OpenJDK は削除にあたり、代替として -Xverify:all を挙げています(JDK-8339918)。

# 検証を強めるために -Xfuture を付けていたなら
-Xverify:all        # JDK 24 / 25 で受理される(実測)

厳密検証のために意図して付けていたのなら、消すだけでは検証が静かに緩みます。-Xverify:all へ読み替えてください。-checksource / -cs / -noasyncgc には代替がありません(同 release note)。消すだけで済みます。

-Xverify:none は別物です。こちらは検証を切る指定で、JDK 13 で非推奨になったものの JDK 25 でもまだ警告つきで起動します。取り違えないでください。)

-t-tm も JDK 24 の削除一覧にありますが、これは 17→24 の境界にはなりません。launcher が -t/-tm-Xt/-Xtm に変換して VM へ渡していただけで、その -Xt/-Xtm 自体がずっと未サポートだったからです。JDK 17 の時点で既に拒否されます(実測)。24 の削除は、死んだ変換コードの掃除です。)

フラグを消せないとき:IgnoreUnrecognizedVMOptions

-XX:+IgnoreUnrecognizedVMOptions を付けると、-Xnoagent を残したままでも起動します(実測)。

-XX:+IgnoreUnrecognizedVMOptions -Xnoagent   →   起動する

名前は「Unrecognized VM Options」ですが、-XX の VM オプションだけでなく、-X の launcher オプション(-Xnoagent)も黙らせます。ただしこれは起動を通すだけです。他の未知オプションも一律に飲み込むので、フラグを打ち間違えてもエラーになりません。恒久的な設定にはせず、出どころを直すまでの足場に留めてください。

切り分け

  • エラー文が Unrecognized VM option 'X'VM が付く・クォートあり) → 弾いているのは HotSpot VM で、-XX: のフラグです。別の記事です。Unrecognized VM option 'UseBiasedLocking'(JDK 17 → 21)CMS のフラグ(Java 8 → 17) を参照してください。
  • -Xnoagent の隣に -Xdebug が並んでいる → ほぼ必ず並んでいます。-Xdebug は起動を止めません——JDK 22 で非推奨になりましたが、25 でも警告つきで起動します(実測)。原因は -Xnoagent のほうです。-Xdebug もついでに消して構いません。
  • 1 つ消したら次で止まった-Xfuture を消したなら、-checksource-cs-noasyncgc が同じ 24 で消えています。まとめて消してください(-Xfuture だけは -Xverify:all に読み替え)。
  • 警告が 1 度も出なかったのに、上げたら拒否された-Xnoagent は非推奨警告が 22 の 1 版だけです。LTS を渡り歩くと、その版を飛ばします。
  • -Xnoagent を消すとデバッグに影響するか → しません。-Xnoagent が止めていたのは JDK 1.1 時代の旧デバッグ機構で、いまのリモートデバッグは -agentlib:jdwp=...-Xrunjdwp の後継)が担っています。両者は無関係です。

検証環境

  • eclipse-temurin@sha256:83177670e43c17769a5402a60601545318e45e63adf634fb5022340e516cded4(openjdk 23.0.2)、ネットワーク不要
  • 再現:java -Xnoagent -cp ... App が JDK 23 で Unrecognized option: -Xnoagent → 終了コード 1(main()APP_STARTED は出力されない)
  • 修正:-Xnoagent を外して同じ 23.0.2 で終了コード 0・APP_STARTED・シグネチャ消滅(Java のソースは再現・修正で同一)
  • 17/21 は無警告・22 は非推奨警告・23 以降は拒否の版境界、-Xfuture が 17 から警告を出し 24 で削除されること、-checksource/-cs/-noasyncgc が 24 で同時に消えること、-t/-tm は 17 で既に拒否されること、-Xverify:all が JDK 24・25 で受理されること、-Xdebug が 23・25 で警告つきで起動すること、-Xmx64m が JDK 25 で問題なく起動すること、IgnoreUnrecognizedVMOptions-Xnoagent を残して起動できることは、eclipse-temurin の 17.0.19 / 21.0.11 / 22.0.2 / 23.0.2 / 24.0.2 / 25.0.3(いずれも digest 固定)でそれぞれ実行して確認しました
  • -Xnoagent が JDK 1.1 時代の旧デバッグ機構(sun.tools.agent)を止める指定だったこと、-Xfuture の代替が -Xverify:all であること、-t/-tm の変換が launcher 共通の挙動だったことは、OpenJDK の一次情報(JDK-8312072 / JDK-8339918)に拠ります。-Xfuture が実際にどれだけ検証を強めていたかは実測していません
  • 上記以外のパッチ版は網羅していません

検証(machine-verified)

この修正は eclipse-temurin@sha256:83177670e43c17769a5402a60601545318e45e63adf634fb5022340e516cded4 のバージョン固定コンテナ内で再現し、修正後に Unrecognized option: -Xnoagent のシグネチャが消えることを機械で確認しています。

verify — run-case.mjs
$ node run-case.mjs jvm/xnoagent-unrecognized-jdk23
● reproduce Unrecognized option: -Xnoagent present ✓
● apply fix exit 0
● re-run Unrecognized option: -Xnoagent gone ✓
PASS verified · eclipse-temurin@sha256:83177670e43c17769a5402a60601545318e45e63adf634fb5022340e516cded4 · signature gone

確認したのは上のイメージの中だけです。別の環境で直らなかった、記述が違う、という場合は 報告してください(対象と検証イメージは件名・本文に入ります)。