Skip to content

Bug/Feature Request: Node 26 fetch HTTP/2 SSE stream buffering hangs MCP connections #2526

Description

@Starefossen

Title

Bug/Feature Request: Node 26 fetch HTTP/2 SSE stream buffering hangs MCP connections

Body

(Note: This issue was investigated and drafted with the help of Google Antigravity / Gemini 3.1 Pro during a debugging session).

The Issue

When running MCP SDK clients (such as mcporter) on Node.js 26.4.0, all Server-Sent Events (SSE) connections fail to initialize and eventually time out with errors like Invalid response body, expected a web ReadableStream.

Root Cause Analysis

Node 26 upgraded its native fetch implementation (backed by undici) to enable HTTP/2 by default. There appears to be a stream buffering regression in undici when handling SSE over HTTP/2. As a result, the initial connection chunks (specifically the endpoint URI required by the MCP client) are buffered and never flushed to the client's ReadableStream, causing the connection handshake to stall indefinitely.

Evidence & Workaround

  • Failure: On Node 26.4.0, standard MCP SSE connections hang completely.
  • Success: By overriding the global fetch dispatcher to force HTTP/1.1, the streams flow instantly and 100% of the MCP server connections succeed.

Here is the exact shim that resolves the issue locally:

import { setGlobalDispatcher, Agent } from "undici";

// Force HTTP/1.1 to bypass the Node 26 HTTP/2 SSE streaming bug
const agent = new Agent({
  allowH2: false
});
setGlobalDispatcher(agent);

Proposed Solution

While the root cause lies upstream in Node.js / undici, the MCP SDK could protect its users from this breaking change:

  1. Enforce HTTP/1.1 for SSE: Explicitly configure the fetch transport layer to use HTTP/1.1 (allowH2: false) when running in a Node.js environment, as SSE over HTTP/2 in Node is currently unstable.
  2. Expose Transport Config: Alternatively, expose the underlying fetch request initialization/dispatcher options in the SDK so users can inject custom undici agents when needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions