mastra-ai/mastra · error

SSE connection not established

Error message

SSE connection not established

What it means

In the SSE (legacy) transport integration, POSTs to the messagePath are handled by the stored sseTransport instance, which only exists after a client opened the SSE endpoint. If a POST arrives before any SSE connection was established, the server responds 503 with the plain-text body 'SSE connection not established' instead of processing the message.

Source

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

   *   });
   * });
   *
   * httpServer.listen(1234, () => {
   *   console.log('MCP server listening on http://localhost:1234/sse');
   * });
   * ```
   */
  public async startSSE({ url, ssePath, messagePath, req, res }: MCPServerSSEOptions): Promise<void> {
    try {
      if (url.pathname === ssePath) {
        await this.connectSSE({
          messagePath,
          res,
        });
      } else if (url.pathname === messagePath) {
        this.logger.debug('Received message');
        if (!this.sseTransport) {
          res.writeHead(503);
          res.end('SSE connection not established');
          return;
        }
        // Check for pre-parsed body from middleware like express.json()
        // If not available, let the SDK's handlePostMessage read from the stream
        // (which has built-in size limits and charset handling)
        const parsedBody = await this.readJsonBody(req, { preParsedOnly: true });
        await this.sseTransport.handlePostMessage(req, res, parsedBody);
      } else {
        this.logger.debug('Unknown path:', { path: url.pathname });
        res.writeHead(404);
        res.end();
      }
    } catch (e) {
      const mastraError = new MastraError(
        {
          id: 'MCP_SERVER_SSE_START_FAILED',
          domain: ErrorDomain.MCP,

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Establish the SSE connection (GET on ssePath) and wait for the endpoint/event message before POSTing to messagePath
  2. Ensure both SSE and message paths are routed to the same server instance (sticky sessions / single instance)
  3. Fix client configuration so the MCP SDK's SSE client (which sequences SSE then POST) is used instead of hand-rolled requests
  4. Check proxies/load balancers for SSE timeouts or buffering that kill the connection
Defensive patterns

Strategy: retry

Try / catch

async function postMessage(url, body, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const res = await fetch(url, { method: 'POST', body });
    if (res.status !== 503) return res;
    await new Promise(r => setTimeout(r, 500 * (i + 1))); // SSE may not be open yet
  }
  throw new Error('SSE connection never established; check client transport setup');
}

Prevention

When it happens

Trigger: POSTing a JSON-RPC message to the messagePath endpoint when no GET request to the ssePath has completed; race where a client sends its initialize message before the SSE stream is connected; load balancer routing the POST to a different instance than the one holding the SSE connection.

Common situations: curl-based testing that POSTs to /message without first opening the SSE stream; clients constructed with the wrong SSE URL so the stream never opens; multi-instance deployments without sticky sessions; SSE connection dropped (proxy timeout) while the client keeps POSTing.

Related errors


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