claude -p hangs permanently after mid-session MCP tool call returns fetch error

Resolved 💬 2 comments Opened Mar 30, 2026 by n-backman Closed Apr 17, 2026

Summary

claude -p (v2.1.87) hangs permanently when an MCP tool call fails with "fetch failed" mid-session over the Streamable HTTP transport. The process stays alive (event loop runs, timers fire) but never makes another API call. The conversation is permanently stuck.

Reproduction

  1. Start claude -p with --mcp-config pointing to HTTP MCP servers
  2. The model makes several successful MCP tool calls
  3. One MCP tool call fails with a transport-level error ("fetch failed" / 502)
  4. The error is recorded as is_error: true in the conversation
  5. Expected: Model receives the error and continues (makes next API call)
  6. Actual: Process hangs forever — no further API calls, no stdout output

Evidence

Observed across 3 concurrent claude -p processes (all v2.1.87, ARM64 Alpine container):

  • Each process was actively working (making API calls, running MCP tools)
  • Each hit a transient "fetch failed" from an HTTP MCP server
  • Each went permanently silent after the error tool_result was recorded
  • Processes remained alive for 30+ minutes: event loop running (epoll_pwait with 1s timeout), ~3 context switches/sec, 91-95 MB RSS
  • Zero TCP connections after the hang — no API calls being attempted
  • .claude/projects/-app/{sessionId}.jsonl shows conversation ends at the error tool_result

Process state during hang

  • Main thread: epoll_pwait (syscall 22) on eventpoll fd, 1000ms timeout
  • I/O thread: epoll_pwait with infinite timeout
  • 8 worker threads: futex (idle)
  • 0 TCP sockets open (verified via /proc/{pid}/fd/)
  • Voluntary context switches increasing at ~3/sec (timer wakeups only)

Conversation log pattern (from .jsonl)

assistant: tool_use cortex_synapse_search(...)   ← succeeds
user: tool_result [results]
assistant: tool_use cortex_synapse_search(...)   ← parallel call
user: tool_result "fetch failed" (is_error: true)
                                                  ← HANGS HERE, no more entries

Key distinction

  • Clean failure at init (MCP server not reachable when session starts): Handled gracefully — model notes "server not connected" and adapts
  • Dirty failure mid-session (MCP server was connected, some calls succeeded, then one fails): Process hangs permanently

Reproduction test

Running the exact same command (claude -p + same prompt + same --mcp-config + same --model claude-opus-4-6 + same --allowedTools) immediately after the hang succeeds in 2-5 seconds. The issue is triggered by transient MCP transport failures, not persistent misconfiguration.

Environment

  • Claude Code: 2.1.87
  • Platform: Linux aarch64 (Alpine, Docker container)
  • MCP transport: Streamable HTTP ("type": "http" in mcp-config)
  • Model: claude-opus-4-6 (also observed with sonnet)
  • Auth: OAuth token (CLAUDE_CODE_OAUTH_TOKEN)

Impact

In automated/headless environments (CI, job queues), these hung processes consume pool slots indefinitely. The only recovery is external kill + resubmit. Safety-net timeouts (e.g., 4 hours) are the only failsafe, which is far too slow for interactive job systems.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗