mastra-ai/mastra · error

Bad Request: No valid session ID provided for non-initialize

Error message

Bad Request: No valid session ID provided for non-initialize request

What it means

For stateful Streamable HTTP, every POST other than the initial initialize request must carry a valid session id header. If a POST arrives without one, the server responds 400 with JSON-RPC code -32000 and message 'Bad Request: No valid session ID provided for non-initialize request', because it cannot route the message to any session transport.

Source

Thrown at packages/mcp/src/server/server.ts:2210

                // Also clean up the server instance for this session
                if (this.httpServerInstances.has(closedSessionId)) {
                  this.httpServerInstances.delete(closedSessionId);
                  this.logger.debug('Cleaned up server instance for closed session', { sessionId: closedSessionId });
                }
              }
            };

            // Connect the new server instance to the new transport
            await sessionServerInstance.connect(transport);

            // Handle the initialize request. This assigns the session ID and
            // triggers onsessioninitialized, which stores the transport and
            // server instance for the session.
            return await transport.handleRequest(req, res, body);
          } else {
            // POST request but not initialize, and no session ID
            this.logger.warn('Received non-initialize POST request without session ID');
            res.writeHead(400, { 'Content-Type': 'application/json' });
            res.end(
              JSON.stringify({
                jsonrpc: '2.0',
                error: {
                  code: -32000,
                  message: 'Bad Request: No valid session ID provided for non-initialize request',
                },
                id: (body as any)?.id ?? null, // Include original request ID if available
              }),
            );
          }
        } else {
          // Non-POST request (GET/DELETE) without a session ID
          this.logger.warn('Received request without session ID', { method: req.method });
          res.writeHead(400, { 'Content-Type': 'application/json' });
          res.end(
            JSON.stringify({
              jsonrpc: '2.0',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Send an initialize request first and echo the returned mcp-session-id header on every subsequent request
  2. Use the official MCP SDK client transport, which manages the session id automatically
  3. Check that proxies/middleware/CORS exposed headers preserve the mcp-session-id header
  4. If you don't need sessions, run the server in stateless mode (serverless: true or sessionIdGenerator: undefined) where this requirement doesn't apply

Example fix

// before
await fetch('http://localhost:4111/mcp', { method: 'POST', body: rpc }); // no session header
// after
const init = await fetch(url, { method: 'POST', headers: jsonHeaders, body: initRpc });
const sessionId = init.headers.get('mcp-session-id');
await fetch(url, { method: 'POST', headers: { ...jsonHeaders, 'mcp-session-id': sessionId }, body: rpc });
Defensive patterns

Strategy: validation

Validate before calling

function requireSessionHeader(headers, isInitialize) {
  if (!isInitialize && !headers['mcp-session-id']) {
    throw new Error('Non-initialize MCP requests must include the mcp-session-id header');
  }
}

Try / catch

if (res.status === 400) {
  const body = await res.json();
  if (body?.error?.code === -32000 && String(body.error.message).includes('session ID')) {
    // re-run initialize, capture mcp-session-id, then retry the request
  }
}

Prevention

When it happens

Trigger: POSTing tools/call, notifications, or any non-initialize JSON-RPC message without the mcp-session-id header; using a hand-rolled HTTP client that never stores and replays the session id returned at initialize; proxy/gateway stripping the session header.

Common situations: Custom MCP clients built with fetch instead of the SDK; header-filtering middleware or CORS configurations dropping mcp-session-id; calling the endpoint directly (curl/Postman) after copying only an initialize example; stateless serverless callers hitting a stateful server.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/00d8decb586516f2. Report an issue: GitHub.