arc network は一つの問いに答えます:このマシンは arc が必要とする形で外の世界に到達できるか? サブコマンドは doctor の 1 つだけで、4 つのチェック —— プロキシ検出、DNS、HTTPS リクエスト、WebSocket ハンドシェイク —— を実行し、それぞれを独立した行で報告します。分けて報告するのは意図的なものです:「DNS は解決できるがプロキシが CONNECT を拒否する」と「何も解決できない」は異なる障害で修正方法も異なり、単一の pass/fail ではどちらに当たっているのかが見えなくなってしまいます。
arc 2.0.0-beta.48(commit 5a5316bde、2026-09-10)に対して取得したものです。バージョン番号だけではこれを特定できません —— 2.0.0-beta.48 は今回のサイクルで複数のバイナリを指してきました —— そのため、以下の内容をバイト単位で信用する前に arc --version を実行し、その第 3 フィールドである commit を上記のものと比較してください。チェックやフラグはいずれにせよリリース間で変わることがあります。
使用法
arc network doctor [options]グローバルフラグ(概要 を参照):--json、--view、--instance / -i(どのローカル ARC インスタンスか;省略すると default)、および --home(インスタンスのルート;どのインスタンスにするかを選ぶには --instance を使う)。doctor はデーモンと通信しないため、デーモンが動いているかどうかに関わらず動作します。
--target <url>:プローブする HTTPS URL(デフォルトhttps://main.abtnetwork.io/)--ws-target <url>:プローブする WSS URL(デフォルトwss://main.abtnetwork.io/api/websocket?vsn=2.0.0)
arc network は単独ではコマンドではありません:Please specify a subcommand とサブコマンド一覧を表示して、exit 5 します。
例(すべて到達可能、プロキシなし)
$ arc network doctor
Outbound network doctor
Proxy:
(none)
Checks:
✓ proxy-discovery no proxy environment variables
✓ direct-dns main.abtnetwork.io → 198.18.0.38
✓ https-through-proxy HTTP 200 direct
✓ wss-through-proxy WSS handshake direct
OK4 つすべてが通ると exit 0 です。2 つのネットワークチェックは、プロキシが関与していない場合でも名前に through-proxy を含み続けます。実際にどのルートが使われたかを示すのは detail の列です —— ここでは direct です。
direct-dns の行にあるアドレスは、あなた自身のリゾルバが返したものです。したがって、ここと異なるものを見ることを想定してください。キャプティブ/フィルタリングするリゾルバのあるネットワークでは、その名前が実際には持っていないアドレスが返ることさえあります。これは脚注以上に重要です。というのも、失敗がどの層に帰属するかはリゾルバに追随するからです:存在しない名前は、リゾルバが正直にそう答える場合は DNS の失敗として報告され、それでも何らかのアドレスを返すリゾルバの場合は接続または TLS の失敗として報告されます。doctor の結果に驚いたときは、どのチェックが赤くなったかを信じる前に、まずその名前を別の手段で独立に確認してください。
例(プロキシは設定されているが応答しない)
$ HTTPS_PROXY=http://127.0.0.1:9 HTTP_PROXY=http://127.0.0.1:9 arc network doctor
ERROR: Outbound network doctor
Proxy:
HTTP_PROXY http://127.0.0.1:9/
HTTPS_PROXY http://127.0.0.1:9/
Checks:
✓ proxy-discovery proxy environment variables present (credentials redacted)
✓ direct-dns main.abtnetwork.io → 198.18.0.38
✗ https-through-proxy PROXY_CONNECT_FAILED connect ECONNREFUSED 127.0.0.1:9
✗ wss-through-proxy PROXY_CONNECT_FAILED connect ECONNREFUSED 127.0.0.1:9
FAILEDどれか 1 つでもチェックが失敗すれば exit 5 です。1 行目の ERROR: というプレフィックスは、CLI が持つ「この実行は失敗した」ことを示す唯一のマーカーです(arc#6301)—— どのコマンドが報告する失敗でも、メッセージは必ずこの同じ形で始まるので、呼び出し側はどのコマンドが出したかを知らなくてもエラーの先頭を見つけられます。緑のままだったものに注目してください:proxy discovery が通ったのは、それがどの変数が設定されているかだけを報告し、プロキシが実際に機能するかどうかは報告しないからです。DNS が通ったのは、名前解決がそもそもプロキシを一切経由しないからです。失敗した 2 つは、汎用的なタイムアウトではなく理由 —— PROXY_CONNECT_FAILED —— を名指ししており、これが DNS やターゲットホストではなくプロキシを見るべきだということを教えてくれます。プロキシの URL は、資格情報を伏せた状態で表示されます。
機械可読な出力
--json は同じ実行結果を構造化データとして出力します。以下は上記の失敗した実行のものです。興味深いフィールドが現れるのは失敗時だからです:失敗した各チェックには code が追加され、required / affectsOverallHealth が、判定がどの結果から計算されているかを示します。ここでは direct-dns が required: false に切り替わっています —— プロキシが関与すると、直接解決できるかどうかはもはや判定の根拠ではなくなります。
$ HTTPS_PROXY=http://127.0.0.1:9 HTTP_PROXY=http://127.0.0.1:9 arc network doctor --json
ERROR: {
"proxy": {
"httpProxy": "http://127.0.0.1:9/",
"httpsProxy": "http://127.0.0.1:9/"
},
"checks": [
{
"name": "proxy-discovery",
"ok": true,
"status": "pass",
"required": true,
"affectsOverallHealth": true,
"detail": "proxy environment variables present (credentials redacted)"
},
{
"name": "direct-dns",
"ok": true,
"status": "pass",
"required": false,
"affectsOverallHealth": false,
"detail": "main.abtnetwork.io → 198.18.0.38"
},
{
"name": "https-through-proxy",
"ok": false,
"status": "fail",
"required": true,
"affectsOverallHealth": true,
"code": "PROXY_CONNECT_FAILED",
"detail": "connect ECONNREFUSED 127.0.0.1:9"
},
{
"name": "wss-through-proxy",
"ok": false,
"status": "fail",
"required": true,
"affectsOverallHealth": true,
"code": "PROXY_CONNECT_FAILED",
"detail": "connect ECONNREFUSED 127.0.0.1:9"
}
],
"ok": false
}上記の先頭にある ERROR: は本物で、コピー&ペーストの誤りではありません:失敗した実行では、人間向けの例と同じ単一の出口プレフィックスが、JSON の前にも、開き括弧 { と同じ行に現れます。失敗したコマンドのメッセージ全体は —— 人間向けテキストであれ JSON であれ、この CLI はその時点でそれらを区別しないため —— 一度だけこのマーカーを前置されるからです。非ゼロ終了でパースする前にこの 1 トークンを取り除くか、あるいは stderr を JSON としてパースしようとする代わりに終了コードで分岐してください。正常な実行は同じ形をしていますが、code フィールドがなく、すべての status が pass、proxy が空オブジェクト、トップレベルの ok が true です —— そして ERROR: プレフィックスもありません。これは失敗時にのみ現れるからです。これをパイプする前に知っておく価値があることがもう一つあります:失敗した実行ではstdout は 0 バイトです —— メッセージ全体が、プレフィックスも含めてすべて stderr に流れます —— そのため arc network doctor --json | jq は、エラーオブジェクトではなく何も見えません。まず終了コードを確認してください。そうしないと、実際の失敗ではなく自分の jq フィルターのデバッグをすることになります。
2 つの target はそれぞれ独立して動きます。--target は HTTPS プローブと、それに付随する DNS チェックのターゲットを変えます —— https://arc.arcblock.io/ をプローブすると、デフォルトのホストではなく arc.arcblock.io → … が direct-dns の行に載ります —— 一方 --ws-target は WebSocket プローブだけを変え、DNS は --target が指す名前のままです。したがって --ws-target を閉じたポートに向けると、ちょうど 1 つのチェックだけが失敗します:
$ arc network doctor --ws-target wss://127.0.0.1:9/
ERROR: Outbound network doctor
Proxy:
(none)
Checks:
✓ proxy-discovery no proxy environment variables
✓ direct-dns main.abtnetwork.io → 198.18.0.38
✓ https-through-proxy HTTP 200 direct
✗ wss-through-proxy UPSTREAM_REJECTED
FAILEDここでは、どのマシンでもプローブが同じように失敗するように、リテラルなアドレスと閉じたポートが選ばれています —— 解決すべき名前がなければ、異議を唱えるリゾルバも存在しません。失敗した層を名指しするのは code、つまり UPSTREAM_REJECTED であり、PROXY_CONNECT_FAILED / DIRECT_DNS_FAILED / TLS_FAILED とは区別されます。その後に続く自由形式の detail は保証されておらず、この取得では空でした —— 即座に拒否された loopback 接続は、その下の socket 層に何も言うことを残しませんでした。detail のテキストにマッチさせず、code にマッチさせてください。構造化して扱いたい場合は --json を使ってください。この 2 つのフラグは、デフォルトには到達できるが、本当に確認したいホストには到達できない場合に使います。