n8n-io/n8n · error · Error
SSE response has no body
Error message
SSE response has no body
What it means
After the SSE response passes res.ok, the client verifies a readable body exists. A 2xx with no body stream is a contract violation (the runtime/proxy closed the stream early) and the client cannot assemble events, so it fails fast rather than hanging on an empty reader.
Source
Thrown at packages/@n8n/instance-ai/evaluations/clients/sse-client.ts:44
cookie: string,
handler: (event: SseEvent) => void,
signal: AbortSignal,
): Promise<void> {
const res = await fetch(url, {
headers: {
cookie,
Accept: 'text/event-stream',
},
signal,
});
if (!res.ok) {
const text = await res.text();
throw new Error(`SSE connection failed (${res.status}): ${text}`);
}
if (!res.body) {
throw new Error('SSE response has no body');
}
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
// Accumulator for partial lines (SSE data can be split across chunks)
let buffer = '';
// Current event being assembled
let eventId: string | undefined;
let eventType: string | undefined;
let dataLines: string[] = [];
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += value;View on GitHub (pinned to 5ac6606e81)
Solutions
- Disable response buffering / SSE-unfriendly compression on any proxy in front of n8n.
- Run on a runtime that exposes ReadableStream bodies (modern Node/Deno/browsers).
- If reproducible, capture the raw response headers to confirm Content-Type:text/event-stream and presence of a body.
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the response advertises a stream:
const probe = await fetch(url, { headers: { cookie, Accept: 'text/event-stream' }, signal });
if (probe.ok && !probe.body) throw new Error('proxy/runtime swallowed SSE body'); Type guard
const hasReadableBody = (r: Response): r is Response & { body: ReadableStream } =>
Boolean(r.body); Prevention
- Disable SSE buffering on proxies in front of n8n.
- Use a runtime that exposes ReadableStream bodies.
- Set Content-Type:text/event-stream and disable compression for the events route.
When it happens
Trigger: A proxy or middleware that returns 200 and swallows the body; a server-side bug closing the stream immediately; a fetch implementation that does not expose streaming bodies.
Common situations: Reverse proxies buffering SSE; older runtimes where res.body is undefined for streams; misconfigured compression.
Related errors
- SSE connection failed (${res.status}): ${text}
- Failed to fetch provider catalog: ${response.statusText}
- Supabase upsert failed: ${error.message}
- Supabase query failed: ${error.message}
- Supabase delete failed: ${error.message}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/3c76fe60f58f4ed0.
Report an issue: GitHub.