Skip to content

Uncatchable AssertionError: assert(!this.paused) on socket end #5360

Description

@andreypopp

Description

If the consumer doesn't read the body immediately, the HTTP/1 parser pauses under
backpressure. When the socket ends (FIN), onHttpSocketEnd calls parser.finish(),
which asserts !this.paused. Since the parser is paused, this throws an uncatchable
AssertionError from the socket 'end' handler and crashes the process.

AssertionError [ERR_ASSERTION]: assert(!this.paused)
    at Parser.finish (.../undici/lib/dispatcher/client-h1.js:374:5)
    at Socket.onHttpSocketEnd (.../undici/lib/dispatcher/client-h1.js:951:30)

onHttpSocketEnd doesn't check parser.paused before calling finish().

Reproduction (minimised with Claude Code)

import { createServer } from "node:net";
import { fetch } from "undici";

const BODY = Buffer.alloc(64 * 1024, 0x61);

const server = createServer((sock) => {
  sock.once("data", () => {
    sock.write(
      "HTTP/1.1 200 OK\r\n" +
        `Content-Length: ${BODY.length}\r\n` +
        "Connection: close\r\n\r\n",
    );
    sock.write(BODY);
    sock.end(); // FIN
  });
});

server.listen(0, "127.0.0.1", async () => {
  const { port } = server.address();
  const res = await fetch(`http://127.0.0.1:${port}/`);
  void res; // never read the body -> parser pauses -> crash on FIN
  await new Promise((r) => setTimeout(r, 1000));
  console.log("no crash"); // never reached
});

The 64 KiB body is the body highWaterMark — the smallest size that pauses while still
arriving in one socket read, which makes this deterministic. It's not a fixed value:
the real trigger is "paused with the read buffer drained when FIN arrives," so the
size is network-dependent (intermittent across sizes over a real connection).

Expected vs actual

  • Expected: clean end, or a catchable error. A peer closing a non-keep-alive
    response under backpressure shouldn't crash the process.
  • Actual: uncatchable AssertionError, exit code 1.

Environment

  • undici 8.3.0 (and current main)
  • Node.js v22.22.2, Linux

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions