[BUG] claude.ai custom MCP connectors send stale session IDs after service restart — tools load but all calls fail, disconnect/reconnect does not fix
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Custom Streamable HTTP MCP connectors (via supergateway 3.4.3, --stateful) load tools successfully in claude.ai web conversations, but every tool call fails with "Error occurred during tool execution."
Nginx debug logging reveals claude.ai is sending a stale Mcp-Session-Id header that doesn't exist on the server. supergateway correctly returns 400. claude.ai does not fall back to re-initializing a fresh session — it just surfaces the error.
This stale session ID persists across disconnecting/reconnecting the connector, fully deleting and re-adding the connector, using an incognito browser window, and starting new conversations. The Connectors settings UI also exhibits a related bug: after clicking "Disconnect," reloading the page reverts the connector to connected state as though the disconnect never committed.
Two custom connectors on the same host (different ports) broke simultaneously. The server is confirmed healthy — external curl through Cloudflare succeeds and returns a valid session.
What Should Happen?
When a tool call receives a 400 due to an invalid session ID, claude.ai should discard the cached session ID and send a fresh initialize request to obtain a new one.
Disconnecting or deleting a connector should reliably clear all cached state, including any stored session ID.
Error Messages/Logs
# User-visible error (in claude.ai conversation):
"Error occurred during tool execution"
# Nginx debug log showing claude.ai's requests with stale session ID:
# (custom log format capturing $http_mcp_session_id header)
172.70.34.132 - GET /[secret-path] HTTP/1.1 - status:400 body_bytes:29 accept:"text/event-stream" content_type:"-" session_id:"ead943df-8fd9-4839-ae58-611a949e59c4" content_length:"-"
104.23.209.43 - POST /[secret-path] HTTP/1.1 - status:400 body_bytes:105 accept:"application/json, text/event-stream" content_type:"application/json" session_id:"ead943df-8fd9-4839-ae58-611a949e59c4" content_length:"109"
# supergateway response for invalid session ID (confirmed via localhost curl):
{"jsonrpc":"2.0","error":{"code":-32000,"message":"Bad Request: No valid session ID provided"},"id":null}
# supergateway journal shows NO entries for claude.ai's requests —
# the 400 rejection happens at Express's HTTP layer before MCP logging.
# External curl through Cloudflare SUCCEEDS with no session ID (fresh initialize):
$ curl -X POST https://[domain]/[secret-path] \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
HTTP/2 200
mcp-session-id: b4b6586d-c5f5-40f9-ada1-873c05776f0d
event: message
data: {"result":{"protocolVersion":"2025-03-26","capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"memory-server","version":"0.6.3"}},"jsonrpc":"2.0","id":1}
# Cloudflare security analytics show all requests matched the skip rule (Action: Skip).
# Requests are reaching nginx and being proxied to supergateway — Cloudflare is not blocking.
Steps to Reproduce
- Set up a custom MCP server using supergateway 3.4.3 with
--stateful --outputTransport streamableHttp, behind nginx and Cloudflare - Add the connector in claude.ai (Settings → Connections) — tools load and work normally
- Restart the MCP server service (
sudo systemctl restart memory-mcp) - Open a new claude.ai conversation and attempt any tool call
- Tool call fails with "Error occurred during tool execution"
- Go to Settings → Connections → click Disconnect on the connector
- Reload the page — connector shows as connected again (disconnect did not persist)
- Delete the connector entirely and re-add it
- Open a new conversation in an incognito window — same failure
- Check nginx logs: claude.ai is still sending the same stale
Mcp-Session-Idfrom step 2
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
Unknown — connectors were working as recently as early April 2026. The issue may be related to changes deployed around the April 6–10 outage period.
Claude Code Version
N/A — this bug is in the claude.ai web MCP connector client, not Claude Code CLI. Filing here because this repo is the standard location for MCP connector issues.
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Stack: supergateway 3.4.3 (Node, --stateful streamableHttp) → nginx (proxy_pass to localhost:PORT/mcp) → Cloudflare (orange cloud, skip rule for MCP paths) → AWS Lightsail (Ubuntu 24.04)
Two connectors affected simultaneously: Both a Bluesky MCP server (port 3000) and a Memory MCP server (port 3001) on the same host broke at the same time, confirming this is not server-specific.
Connector disconnect UI bug: Clicking "Disconnect" in Settings → Connections appears to succeed, but reloading the page reverts the connector to connected/"Configure" state. This may be the same underlying issue — the cached session state is not being cleared.
Possibly related:
- March 31 incident: "connectors became unavailable in the Claude.ai desktop application"
- #44361: Slack MCP connector not recovering after April 6 service disruption
4 Comments
Found 1 possible duplicate issue:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
The stale
Mcp-Session-Idsurviving connector deletion and reconnection is a session identity bug — the cached session ID represents a past identity handshake that is no longer valid, and the client treating it as authoritative after the session is gone is analogous to continuing to use an expired auth token.The core issue: session ID and session identity are treated as equivalent, but they are not. A session ID is a reference to a particular server-side session object. Session identity is the trust relationship between client and server established during initialization. When the server restarts, the session object is gone, but the client still holds the reference — and incorrectly treats the reference as the identity.
The fix direction (discard cached session ID on 400 and re-initialize) is correct, but worth extending:
1. Session ID as ephemeral reference, not identity. The
Mcp-Session-Idshould be treated as ephemeral — valid only for the lifetime of the server process that issued it. A restart event (detectable via connection drop + reconnect) should automatically invalidate all cached session IDs, triggering fresh initialization.2. Agent identity separate from session ID. If Claude Code has an agent identity (via an
X-Agent-IDheader or equivalent), that identity persists across session restarts. The server can use the agent identity to restore session context for known agents — returning a new session ID that continues a previous conversation rather than starting cold. The stale session ID problem only occurs because session ID is the sole identity mechanism rather than one layer of a two-layer (agent identity + session reference) model.3. Connector state sync. The disconnect-but-reverts-to-connected UI bug suggests the local state and server state are out of sync — same root cause as the session ID issue. A single atomic "forget this connector" operation that clears all local state (session ID, connection status, cached tool definitions) before the UI update would prevent the revert.
Update: Identified the root cause. This is a supergateway bug, not a claude.ai bug.
supergateway 3.4.3 returns HTTP 400 for unknown session IDs; the MCP spec requires 404. The 404 is what tells claude.ai to discard the stale session and re-initialize. With 400, claude.ai doesn't know the session is gone and stays stuck.
Patching supergateway to return 404 for unknown session IDs resolves the tool call failures — auto-recovery after server restarts works correctly. Details and a three-line fix at supercorp-ai/supergateway#123.
The connector disconnect UI bug (disconnect reverts to connected state on page reload) is still a separate claude.ai issue and remains valid.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.