AI Router · CLI · MCPCheapest eligible quotes before you create
troubleshooting · retention

Fix MCP session-not-found 404 errors

Discard an expired legacy session and reinitialize only when the negotiated protocol uses sessions.

Connect OfflineCreator with OAuth
Output contact sheet

First decide whether this connection is allowed to have a session

Do not retry a session-not-found response until you know which MCP protocol revision the connection is using. The 2026-07-28 Streamable HTTP revision removed protocol-level sessions and the Mcp-Session-Id header. A server that supports only that revision should ignore a legacy session header rather than create or echo one. On that revision, an unimplemented RPC method can produce 404 with a Method not found JSON-RPC error; clearing a session ID is not the diagnosis.

For Streamable HTTP revisions from 2025-03-26 through 2025-11-25, a server could return Mcp-Session-Id with a successful InitializeResult. The client then had to return that value on later HTTP requests. Under the 2025-11-25 contract, a 404 on a request that actually carried the assigned session ID means the server no longer recognizes that session. Stop sending the stale value and begin a new initialization without any session header.

Transport switch

Classify the 404 from the request and response together

Legacy request carried Mcp-Session-Id
Treat 404 as an unknown or expired sessionFor a negotiated 2025-era sessionful connection, discard the old identifier and initialize again without it. Repeating the same request with the same identifier cannot restore state that the server no longer owns.
Legacy non-initialize request carried no session ID
Expect 400, not session-not-found 404The 2025-11-25 specification distinguishes a missing required session header from an unknown supplied value. A missing value should produce 400; an unknown or terminated value produces 404. This difference directs the recovery path.
Connection uses revision 2026-07-28
Investigate method, route, and compatibilityThat revision has no protocol session to refresh. Read the JSON-RPC body and verify the endpoint and request metadata. The current transport specification uses 404 plus Method not found when the server does not implement the requested RPC method.
Error appears after deploy or only on some requests
Check where the session table livesCurrent Python and TypeScript SDK documentation describes legacy session state as process-local unless an application adds routing or shared infrastructure. A restart can erase it; a different worker may never have owned it.
Compatibility stamp

Capture a safe, version-pinned reproduction

Record the client name and version, SDK package and version, MCP endpoint path, negotiated protocol revision, HTTP method, status, and redacted JSON-RPC error body. For the request header, record only absent or present plus a short one-way fingerprint; never paste the session ID, authorization token, cookie, or another reusable credential into an issue. Note whether the failure followed idle time, a server deploy, a client reconnect, or a scale-up event.

Reproduce with one harmless request such as tools/list. Preserve the initialization response headers for a 2025-era connection, then compare the fingerprint of its assigned session ID with the failing request. If they differ, inspect client storage and header construction. If they match but the server returns 404, inspect server logs and routing. If the negotiated revision is 2026-07-28, omit this comparison because the protocol no longer assigns a session ID.

Failure trace

Choose recovery from the observed boundary

One old session fails after a restart
Create a fresh client connectionEnd the failed connection and perform a fresh initialization with no Mcp-Session-Id. Do not replay a state-dependent operation automatically until you know whether it is idempotent, because server-side subscriptions or other per-session state may not survive.
Failures alternate behind multiple workers
Fix legacy routing or remove transport sessionsFor a legacy sessionful deployment, route each identifier back to the worker that owns its transport, or use the SDK's documented stateless mode where the application does not require session-scoped transport behavior. Do not assume a shared event store also shares the transport instance.
Client keeps reusing the rejected identifier
Verify the exact client or SDK releaseAn open Python SDK issue reproduced this behavior with mcp 1.22.0: the client surfaced Session terminated instead of automatically reinitializing. That issue remains open, so reconnect at the application boundary and verify release notes rather than claiming every current client self-heals.
Server returns 400 for an unknown supplied ID
Check the server SDK versionThe Python SDK merged a v1.x backport in January 2026 that changed unknown or expired IDs from 400 to 404. This repository record proves the branch fix, not which package version an unnamed deployment runs.
Error code index

Separate client recovery from server prevention

The immediate client action on a legacy session-bound 404 is narrow: stop the dead connection, clear the rejected identifier, and initialize again without a session header. Retry only the operation whose semantics you understand. A new transport session does not prove that subscriptions, cursors, progress tokens, or an earlier tool side effect carried over. Rebuild required state explicitly and ask before repeating a potentially mutating call.

The server-side prevention depends on the failure pattern. A burst immediately after deployment is consistent with process-local session tables being replaced. Alternating success and 404 across a stable deployment points toward requests reaching workers with different in-memory tables. TypeScript SDK v2 guidance says a 2025-era sessionful deployment keeps one transport per session and routes requests by Mcp-Session-Id; its current stateless default avoids session affinity for the 2026 revision.

Related circuit

Return to the troubleshooting directory if no request reached the MCP endpoint. Use the authorization-header guide when the trace shows missing bearer credentials rather than a rejected session. Use the token-exchange guide when OAuth metadata or the token endpoint itself returns 404. Keep this page for a version-pinned Streamable HTTP request whose status and body identify an unrecognized legacy session.

Canonical plate

Evidence boundary

The recovery rule and status distinction come from the versioned MCP specifications. Deployment guidance comes from current official TypeScript and Python SDK documentation. The Python pull request is a merged, repository-specific server fix; the Python client issue is an open report tied to mcp 1.22.0 and is qualified as developer evidence, not prevalence or a universal compatibility claim.

The last30days run had degraded coverage and returned no page-specific recent community account strong enough to support a remedy. Digg was rate-limited with HTTP 429, Reddit returned partial results, X was not configured and was not run, and Polymarket was missing from run telemetry. Those access and telemetry gaps do not show that discussion is absent. No MCP endpoint, session credential, production request, load balancer, or client installation was tested during this research.