Claude Media
Claude Codeの応答が止まったときのタイムアウト調整方法

Claude Codeの応答が止まったときのタイムアウト調整方法

Claude Codeがストリーミング応答の停止をどう検知するか、4つのタイマーと関連する環境変数、症状別の調整先をまとめます。

Claude Codeは、APIからのストリーミング応答の停止を、応答受信中の3層+応答開始前の1層、計4種類の独立したタイマーで検知します。既定のタイムアウトは接続経路によって180秒から300秒まで幅があり、CLAUDE_STREAM_IDLE_TIMEOUT_MSをはじめとする環境変数で個別に調整できます。まず画面に出たメッセージから層を当て、その層に効く変数だけを触るのが最短です。

画面のメッセージから、どのタイマーが働いたかを逆引きする

打ち切りの原因は、ターン終了時に出るメッセージの文言でおおよそ絞れます。

画面に出る文言働いた層最初に見る変数
No response from API (waited 3m, then 10m on the retry)働いた層最初の1バイト猶予(1回再送しても無応答)最初に見る変数CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS、API_TIMEOUT_MS
The response stopped arriving. The response above may be incomplete.働いた層バイト単位ウォッチドッグ(接続は開いたままデータだけが止まった)最初に見る変数CLAUDE_STREAM_IDLE_TIMEOUT_MS
Connection lost mid-response働いた層接続断。プロキシやゲートウェイが応答本体を途中できれいに閉じた場合にも出る最初に見る変数経路側の設定
Your computer went to sleep mid-response働いた層PCのスリープ検知最初に見る変数変数では変わらない
Connection lost before a response was produced働いた層思考完了後、テキストもツール呼び出しも始まる前に接続が切れ続けた最初に見る変数経路側の設定
Your computer went to sleep before a response was produced働いた層思考完了後、出力が始まる前のスリープ検知最初に見る変数変数では変わらない
The response stalled before a response was produced働いた層応答ヘッダー後に2回続けて止まり、思考完了後にテキストもツール呼び出しも始まらなかった最初に見る変数CLAUDE_STREAM_IDLE_TIMEOUT_MS

v2.1.227より前の文言は次のとおりです。The response stopped arrivingはResponse stalled mid-stream、Connection lost mid-responseはConnection closed mid-responseでした。古いバージョンの報告を検索するときは旧文言でも当たります。

応答待ちが20秒続くと、スピナーにWaiting for API response · will retry in …と出ます。打ち切りの前段の表示で、見え方は応答待ちの表示の記事で扱っています。応答が不完全になったときの見え方は「Response incomplete」の通知にまとめています。

ストリーミングアイドルウォッチドッグとは何を見張っているか

「ストリーミングアイドルウォッチドッグ」は、公式ドキュメントがこの検知の仕組みに付けた呼び名です。応答を受け取っている最中の3種類に、応答開始前の1種類を足した4つが、それぞれ別の信号を見ています。Claude Code全体の設定の位置づけは、完全ガイドで確認できます。

仕組み

4つのタイマーが見ている信号

  • 最初の1バイト猶予

    応答が始まる前、最初のバイトが届くまでの待ち時間だけを見ます。打ち切ると1回だけ再送します。

  • イベント単位

    パース済みのイベントが来ているかを見ます。バイト単位ウォッチドッグが動く接続では、keep-aliveのバイトでもリセットされます。Vertex AI・Foundry・既定のBedrockでは、keep-aliveではリセットされません。

  • バイト単位

    配線上に1バイトでも届いているかを見ます。keep-aliveもバイトに数えるので、keep-aliveだけが来て本体が来ない接続は見分けられません。

  • ボディアイドル

    バイトの到着だけを見る、粗い監視です。

どの経路でどのタイマーが動くか、既定は何秒かは、次の表のとおりです。

監視レイヤー対象接続既定タイムアウト
最初の1バイト猶予対象接続直接Anthropic API・Claude Platform on AWS(HTTPSプロキシ経由を含む)。ANTHROPIC_BASE_URL / ANTHROPIC_AWS_BASE_URLでゲートウェイ経由にした場合は動作しない。BedrockはCLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK=1でオプトイン、Vertex AI(公式表記はGoogle CloudのAgent Platform)・Foundryでは動作しない既定タイムアウト直接APIで180秒、それ以外で300秒。リクエストボディ32KBごとに1秒加算
イベント単位対象接続全プロバイダー既定タイムアウト300秒
バイト単位対象接続直接API・Claude Platform on AWS・ゲートウェイ接続。Bedrockのvnd.amazon.eventstream応答は既定で無効(CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK=1でオプトイン)。Vertex AI・Foundryでは動作しない既定タイムアウト直接APIで180秒、それ以外で300秒
ボディアイドル対象接続直接API・Claude Platform on AWS以外既定タイムアウト5分

ANTHROPIC_BEDROCK_BASE_URLのようにプロバイダー専用のベースURLで向けたゲートウェイは、バイト単位ウォッチドッグの対象になりません。

応答が止まったときに効く環境変数の早見表

症状効く設定補足
遅いプロキシ経由で「No response from API」が頻発する効く設定CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MSを伸ばす補足最初の1バイトが届くまでの猶予そのものを広げる(v2.1.242以降)。再送側はAPI_TIMEOUT_MSで決まる(次節)
Bedrockのイベントストリーム応答で拡張思考中に切れる効く設定CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK=1を設定しCLAUDE_STREAM_IDLE_TIMEOUT_MSで猶予を調整補足Bedrockのバイト単位監視は既定オフなので、まずオプトインが要る
自前ゲートウェイでkeep-aliveだけ来て本体が来ない接続を早く検知したい効く設定専用の設定は無い補足バイト単位ウォッチドッグはkeep-aliveをバイトとして数えるため検知できない。イベント単位ウォッチドッグはパース済みイベントが約5分来なければ打ち切るので、それが実質の検知上限になる
CIなど無人運用で早期に失敗を確定させたい効く設定CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MSを短縮補足明示指定時の下限は5分にクランプされるCLAUDE_STREAM_IDLE_TIMEOUT_MSと異なり、こちらは下限10秒まで短縮できる(思考の長い沈黙を吸収する用途には向かない)
5分超データが来ない自前ゲートウェイでボディアイドルだけ止めたい効く設定API_FORCE_IDLE_TIMEOUT=0補足ウォッチドッグ自体はこの設定と無関係に動き続ける点に注意

No response from APIの待ち時間は1回目と再送で別々に決まる

最初の1バイトが来ないとき、Claude Codeは1回目と再送で待ち時間を別に決めます。メッセージのwaited 3m, then 10m on the retryは、この2つの実測値です。

くらべる

最初の1バイトを待つ時間

ウォッチドッグ側の値

1回目

CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MSを1以上で指定すると、その値(10秒〜30分にクランプ)。未指定ならバイト単位ウォッチドッグの猶予です。どちらもリクエストボディ32KBごとに1秒が加算されます。

API_TIMEOUT_MS側の値

再送

API_TIMEOUT_MSから1秒引いた時間で、既定では10分弱です。応答を生成し終えるまで返さないプロキシを、再送なら待ち切れるようにするためです。Bedrockだけは再送も1回目と同じ猶予です。

どちらの待ち時間も、正の値のAPI_TIMEOUT_MSから1秒引いた時間を超えません。API_TIMEOUT_MSが11秒未満だと、この猶予自体が無効になります。ここから、切り分けが2通りに分かれます。

  • 1回目が毎回切れて再送で通る場合は、CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MSを上げて1回目の待ちを延ばします
  • 再送も無応答なら、プロキシが応答を溜め込んでいる可能性があります。API_TIMEOUT_MSを上げて再送の待ちを延ばします。Bedrockでは両方を上げます

API_TIMEOUT_MSは、リクエスト1本全体のタイムアウトとしてはRequest timed outエラーの原因にもなる値です。プロキシまわりの設定全体はClaude Codeプロキシ設定で扱っています。API_TIMEOUT_MSだけを上げても、CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MSを指定していなければ1回目の待ちは変わりません。値は上限として働くだけで、バイト単位ウォッチドッグの猶予より長くなる方向には連動しないためです。

環境変数の設定方法

環境変数はセッション開始前にエクスポートするか、settings.jsonのenvに書きます。組織全体に配る場合はmanaged settings経由が確実です。

export CLAUDE_STREAM_IDLE_TIMEOUT_MS=600000
export CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK=1

settings.jsonに書くなら、値は文字列で指定します。

{
  "env": {
    "CLAUDE_STREAM_IDLE_TIMEOUT_MS": "600000",
    "CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK": "1"
  }
}

主要な変数の役割は次の通りです。

変数効果必要バージョン
CLAUDE_STREAM_IDLE_TIMEOUT_MS効果両ウォッチドッグの猶予を一括変更。明示指定時の下限は5分、バイト単位は上限30分でクランプ必要バージョン-
CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS効果バイト単位のみ個別変更。指定時はCLAUDE_STREAM_IDLE_TIMEOUT_MSより優先。10秒〜30分でクランプ必要バージョンv2.1.210以降
CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS効果最初の1バイトが届くまでの猶予を直接指定。10秒〜30分でクランプ、リクエストボディ32KBごとに1秒加算必要バージョンv2.1.242以降
CLAUDE_ENABLE_STREAM_WATCHDOG効果イベント単位ウォッチドッグを1で強制有効・0で強制無効必要バージョン-
CLAUDE_ENABLE_BYTE_WATCHDOG効果バイト単位ウォッチドッグを1で強制有効・0で強制無効(0は最初の1バイト猶予も同時に無効化)必要バージョン-
CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK効果Bedrockのイベントストリーム応答でバイト単位監視をオプトイン必要バージョン-
API_FORCE_IDLE_TIMEOUT効果ボディアイドルタイムアウトを0で無効・1で全プロバイダー有効必要バージョンv2.1.169以降

ウォッチドッグが作動するとClaude Codeはどう振る舞うか

タイマーが打ち切ったあとの挙動は、応答がどこまで進んでいたかで変わります。

  • 応答ヘッダーが届く前(最初の1バイト猶予が切れた場合): 1回だけ自動で再送し、それでも応答がなければNo response from APIでターンを終了します。CLAUDE_CODE_RETRY_WATCHDOG=1を設定している場合は、この1回だけの上限が外れます
  • ヘッダーは届いたがClaudeの出力がまだ何も届いていない場合、または思考を終えたがテキストもツール呼び出しも始まっていない場合: 止まった接続を切ります。10回の再試行枠とは別に、最大1回だけ再発行します。再発行でも同じ止まり方をして思考完了後だった場合は、The response stalled before a response was producedでターンが終わります
  • テキストブロックやツール呼び出しを完了した後、または思考後にそれらを開始した後で、応答全体が終わる前に切れた場合: 完了済みの出力は保持します。完了していたツール呼び出しは実行して、その結果からターンを続けます。あわせて「応答が不完全な可能性があります」という通知を出します。同じツール呼び出しの二重実行を避けるため、リクエストをやり直すことはしません
  • 応答がすでに完了した後に接続が切れた場合: 通知なしでそのままターンを正常終了します

非対話セッション(-p実行やAgent SDK経由)では、テキストだけで途切れツール呼び出しを含まない応答に限り、Claude Codeが自動で最大3回まで続きを促してから通知を出します。サブエージェントは、対話セッションでも同様に続きを促します。

CLAUDE_STREAM_IDLE_TIMEOUT_MSを上げると、ストリームウォッチドッグが有効な間はCLAUDE_ASYNC_AGENT_STALL_TIMEOUT_MSの既定値も一緒に上がります。詳しくは非同期エージェントの停止タイムアウトにあります。

CLAUDE_CODE_RETRY_WATCHDOGとの関係

CLAUDE_CODE_RETRY_WATCHDOG=1を設定していると、リトライの扱いが無人運用向けに変わります。429・529のようなキャパシティ関連のエラーは無期限にリトライし続けます。それ以外の一過性エラー(サーバーエラー・タイムアウト・接続断)は、リトライ上限がv2.1.199以降では既定の10回から300回に上がります。300回はおよそ3時間分のバックオフに当たります。CIジョブや常駐ワーカーのように、人が張り付いていない環境で長時間の障害を待ち切りたい場合に向いた設定です。429・529の待機に上限を付ける方法はMAX_WAIT_MSの解説にあります。

ただし、標準速度のリクエストが支出上限や利用クレジット枯渇を理由にした429を受けた場合は例外で、リトライせずその場でエラーを返します。fast modeのリクエストは扱いが別です。v2.1.239より前は、この種の429も無期限にリトライしていました。

ウォッチドッグはバージョンを重ねて拡張されてきた

4つのタイマーと関連変数は、一度に導入されたものではありません。

あゆみ

ウォッチドッグ関連の変更

  1. v2.1.169API_FORCE_IDLE_TIMEOUTを導入

    ボディアイドルタイムアウトの有効・無効を明示指定できるようになりました。

  2. v2.1.186CLAUDE_CODE_RETRY_WATCHDOGを導入

    旧CLAUDE_CODE_CONNECT_TIMEOUT_MSはno-op化されました。

  3. v2.1.196イベント単位を全プロバイダー既定有効に

    以前は直接API以外では既定オフでした。

  4. v2.1.199ストリーム中盤のサーバーエラーで出力を保持

    完了済みの出力を破棄せず保持するようになりました。

  5. v2.1.210CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MSを導入

    バイト単位だけを個別調整できるようになりました。

  6. v2.1.222ゲートウェイ接続にバイト単位を既定適用

    ANTHROPIC_BASE_URL等のゲートウェイでkeep-aliveが来ているのに、イベント単位の誤検知で切れる問題が解消しました。応答完了後の接続断も、通知なしの正常終了になりました。

  7. v2.1.227メッセージ文言を改称

    Response stalled mid-streamがThe response stopped arrivingに、Connection closed mid-responseがConnection lost mid-responseになりました。

  8. v2.1.239支出上限の429を即エラーに

    RETRY_WATCHDOG使用時も、支出上限・クレジット枯渇の429は無期限リトライしなくなりました。

  9. v2.1.242CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MSを導入

    それ以前は最初の応答がAPI_TIMEOUT_MS(既定10分)を使い切るまで待っていました。

  10. v2.1.246非対話モードで続きを自動要求

    以前は非対話ターンが、そのまま通知付きで終わっていました。

  11. v2.1.261再送の待ち時間を分離

    それ以前は再送も1回目と同じ猶予を待ち、メッセージに待ち時間の表示もありませんでした。

v2.1.229では、Vertex AIやBedrockを上流に持つゲートウェイ接続で、拡張思考中の無通信をSSE keepaliveピングが埋める改善も入りました。こちらはクライアント側のウォッチドッグ設定ではなくサーバー側の対策です。詳細はClaude Code v2.1.229のリリースノートにあります。

よくあるつまずき

  • CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCKだけ設定してタイムアウト値を変えていない場合は、既定のCLAUDE_STREAM_IDLE_TIMEOUT_MS(300秒)が適用されます。拡張思考が5分を超えるタスクでは、オプトインと同時に猶予も伸ばす必要があります
  • 思考完了後の2つの文言も、v2.1.227より前は別でした。Connection closed while thinking, before producing a responseとResponse stalled while thinking, before producing a responseです。古い報告と突き合わせるときは、この旧文言で読み替えます
  • Server error mid-responseは、ストリームの途中で過負荷や5xxのサーバーエラーが返ったときの文言です。v2.1.199以降に出る表示で、ウォッチドッグとは別の原因なので、タイムアウトの変数を触っても変わりません
  • 20秒待ちのスピナー表示は、advisorに相談している間だけ90秒に延びます。相談中は長い間データが来ないことがあるためで、v2.1.214より前は相談中も20秒で出ていました

まとめ

応答が始まる前に止まるのか、始まってから止まるのかで、触る変数が分かれます。前者はCLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MSとAPI_TIMEOUT_MS、後者はCLAUDE_STREAM_IDLE_TIMEOUT_MSです。Bedrockは、バイト単位監視のオプトインが済んでいるかも確認します。

この記事を共有:XはてブLinkedIn