Remote MCP: transient 5xx (e.g. 502) on `initialize` marks server failed for the whole session with no retry/backoff
まだ誰も着手していません。
- 主要言語
- Shell
- スター
- 11.2k
- フォーク
- 1.9k
- 平均マージ
- 14時間 16分
- マージ済み PR(30日)
- 6
説明
Describe the bug
When a remote (type: http) MCP server returns a transient HTTP 5xx (observed: 502 Bad Gateway) on the initialize request at session startup, the CLI records a hard, per-session failure for that server and never retries it for the remaining lifetime of the session. The server then shows as unavailable for the whole run, even though the endpoint recovers seconds later.
This is especially damaging for headless / autopilot workflow (automation) sessions, which cold-start a fresh MCP client on every run: a single unlucky 502 at startup silently disables a required connector for that entire run, with no self-heal. A long-lived interactive session that already completed initialize is unaffected, which makes the failure look inconsistent ("it's green in the app but unavailable in automation").
Observed log (one automation run; server names generic):
[ERROR] rmcp::transport::worker: worker quit with fatal:
UnexpectedServerResponse("HTTP 502 Bad Gateway")
[DEBUG] native_host: Recorded failure for server <Remote Server>: failed to initialize MCP client …
[ERROR] Failed to start MCP client for <Remote Server>: … unexpected server response:
HTTP 502 Bad Gateway, when send initialize request
The endpoint returned a normal 401 auth challenge (healthy) on direct probes seconds later — i.e. the 502 was transient/cold-start, not a real outage.
Affected version
1.0.79-9 (bundled SDK; buildMetadata.gitCommit 65f2c0f). Windows x64. Logic lives in the Rust MCP transport / native_host, so expected to be platform-independent.
Steps to reproduce the behavior
- Configure a
type: httpremote MCP server whose upstream occasionally returns a transient5xxoninitialize(e.g. a scale-to-zero / cold-start backend behind a gateway). - Start a session (or let a scheduled/autopilot workflow run) so the CLI cold-starts the MCP client and sends
initialize. - When
initializehappens to hit the transient502, observe:Recorded failure for server <name>andFailed to start MCP client for <name> … HTTP 502 Bad Gateway.- The server stays unavailable for the entire session — no retry, no backoff, no re-
initialize.
- Probe the same endpoint directly a few seconds later → it responds normally (e.g.
401auth challenge), confirming the 5xx was transient.
Expected behavior
Transient 5xx responses during MCP initialize should be retried with bounded exponential backoff (a few attempts over several seconds) before the server is marked failed. Ideally also allow a later lazy re-initialize/reconnect within the session rather than latching "failed" for the whole run. Distinguish transient transport/gateway 5xx (retryable) from 401/OAuth challenges (handled by the auth flow) and from 4xx config errors (not retryable).
Additional context
- Impact is amplified for scheduled/autopilot automation sessions: they re-cold-start MCP clients every run, so a single startup 502 disables a required connector for that run with no recovery, producing intermittent "connector unavailable" failures that are hard to diagnose.
- A long-lived interactive session that already completed
initializekeeps working, so the same server can appear "connected (green)" in the interactive UI while every fresh automation session reports it unavailable. - Suggested scope: retry policy on the
initializesend path in the streamable-http MCP client worker; treat5xx/transport-closed as retryable with capped attempts + jittered backoff. - Related: the OAuth silent-refresh scope bug tracked in #4464 (a separate failure mode on the same class of remote servers). This retry issue is independent — it fires before auth, on the transport layer.
- OS: Windows x64.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず、Rust MCP transport における streamable-http MCP client worker の initialize の送信パスと、native_host の失敗記録を追跡します。一時的な 502 を再現し、その後、401/OAuth challenge と再試行不可の 4xx レスポンスが既存の処理を維持したまま、バックオフ付きの回数制限された再試行を検証します。完了条件は、復旧した endpoint が失敗状態のまま固定されるのではなく、同じセッション中に initialize できることです。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- rust
- 領域
- networking
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 静か
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 52/100