yikart/AiToEarn · error
-32001
-32001
Error message
Session not found
What it means
The client supplied an Mcp-Session-Id header but no matching transport exists in the server's in-memory `transports` map, so the server replies 404 with JSON-RPC -32001 'Session not found'. The session was either never created on this server instance or was evicted/expired.
Source
Thrown at project/aitoearn-backend/libs/nest-mcp/src/services/mcp-streamable-http.service.ts:276
},
})
// Connect transport to server
await mcpServer.connect(transport)
// Handle the initialization request
await transport.handleRequest(req.raw, res.raw, body)
this.logger.log(`[${transport.sessionId}] New session initialized`)
return
}
// Case 2: Request with session ID
if (sessionId) {
// Check if session exists
if (!this.transports[sessionId]) {
this.logger.debug(`[${sessionId}] Session not found`)
res.status(404).json({
jsonrpc: '2.0',
error: {
code: -32001,
message: 'Session not found',
},
id: null,
})
return
}
// Reject re-initialization attempts
if (this.isInitializeRequest(body)) {
res.status(400).json({
jsonrpc: '2.0',
error: {
code: -32600,
message: 'Invalid Request: Server already initialized',
},View on GitHub (pinned to d3aa8bea5b)
Solutions
- Re-run the initialize handshake to obtain a fresh Mcp-Session-Id and retry the request with it.
- If running multiple instances, enable sticky sessions (session affinity) at the load balancer or back the transport map with a shared store.
- Confirm you are hitting the stateful endpoint, not the stateless one, and that the server wasn't restarted between initialize and this call.
- Add client logic: on 404 'Session not found', transparently re-initialize and replay the request.
Example fix
// before
const res = await post(url, body, { headers: { 'mcp-session-id': savedId } })
// after
let res = await post(url, body, { headers: { 'mcp-session-id': savedId } })
if (res.status === 404) {
savedId = await initialize(url)
res = await post(url, body, { headers: { 'mcp-session-id': savedId } })
} Defensive patterns
Strategy: retry
Validate before calling
const sid = getSessionId()
if (!sid || sidExpiresBefore(Date.now())) {
await reinitialize() // obtain fresh Mcp-Session-Id before calling
} Type guard
function hasSessionId(headers: Record<string, string | undefined>): headers is Record<string, string> & { 'mcp-session-id': string } {
return typeof headers['mcp-session-id'] === 'string' && headers['mcp-session-id'].length > 0
} Try / catch
const res = await post(url, body, sessionHeaders)
if (res.status === 404 && (await res.clone().json())?.error?.message === 'Session not found') {
sessionId = await initialize(url) // re-handshake then retry once
return post(url, body, sessionHeaders)
} Prevention
- Configure sticky sessions when running multiple server instances.
- Re-initialize after any server restart instead of reusing cached session ids.
- Wrap all session-bound calls with automatic re-initialize-and-retry on 404.
- Keep session ids only in memory of the same process that created them.
When it happens
Trigger: POSTing with an Mcp-Session-Id that the current server instance never issued: after server restart, against a different replica behind a load balancer, after the transport was closed/deleted, or a typo'd/stale session id from an old client run.
Common situations: Stateful deployments scaled horizontally without sticky sessions, server restarted mid-conversation while the client kept its old session id, session TTL/cleanup deleting idle transports, or pointing a saved session id at the stateless endpoint.
Related errors
- Session not found
- MCP server not found for session
- -32000
- ResponseCode.ChannelAuthSessionInvalid
- ResponseCode.ChannelAuthPlatformMismatch
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/b189546180e19cb0.
Report an issue: GitHub.