[BUG] MCP client caches stale session ID, doesn't retry on 400

Resolved 💬 3 comments Opened Feb 21, 2026 by tmarkovski Closed Mar 22, 2026

Description

Claude.ai's MCP client caches the mcp-session-id header from a previous connection and replays it on subsequent connections — even after the MCP server has restarted and the session no longer exists. The server returns 400 ("Bad Request: No valid session ID provided") and the client does not recover by dropping the cached session and re-initializing.

Expected behavior

When the server returns 400 for an unknown/expired session ID, the client should discard the cached mcp-session-id and retry the connection with a fresh initialize request (no session header).

Actual behavior

The client keeps sending the stale session ID on every request (GET and POST to /mcp), receives 400 each time, and never retries without it. The only workaround is to fully remove and re-add the MCP integration in Claude.ai.

Steps to reproduce

  1. Connect Claude.ai to a remote MCP server (streamable HTTP transport)
  2. Successfully establish a session (server assigns mcp-session-id)
  3. Restart/redeploy the MCP server (in-memory sessions are lost)
  4. Try to use the MCP integration — all requests fail with 400

Debug evidence

Server-side ASGI middleware captured the incoming requests after a redeploy:

>>> MCP GET
  ct: <none>
  accept: text/event-stream
  session: 4daa7624daf749c8b5893c1e5b5c4808    <-- stale session ID

>>> MCP POST
  ct: application/json
  accept: application/json, text/event-stream
  session: 4daa7624daf749c8b5893c1e5b5c4808    <-- same stale session ID

The session 4daa7624... no longer exists on the server. Per the MCP streamable-HTTP spec (streamable_http_manager.py), an unknown session ID returns 400.

Environment

  • MCP server: FastMCP 2.13.0.2, Python, hosted on Azure Container Apps
  • Transport: Streamable HTTP
  • Client: Claude.ai (web)

Workaround

Remove the MCP integration from Claude.ai and re-add it to clear the cached session.

View original on GitHub ↗

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