Skip to content

Failed requests can sometimes crash the Node.js process with EPIPE. #10558

@terite

Description

@terite

In production our Node.js processes occasionally crash with the following uncaughtException

node:events:486
      throw er; // Unhandled 'error' event
      ^

Error: write EPIPE
    at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:87:19)
Emitted 'error' event on Socket instance at:
    at emitErrorNT (node:internal/streams/destroy:170:8)
    at emitErrorCloseNT (node:internal/streams/destroy:129:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:89:21) {
  errno: -32,
  code: 'EPIPE',
  syscall: 'write'
}

After some debugging we were able to associate the crash with our use of Axios. Attached is a single-file reproduction that crashes every time on my machine. I am using Node.js v24.13.0 and Axios v1.13.6.

I believe the error is due to a missing error event handler on the request socket when using the http adapter.

This issue appears to be related to #3770 and #3780

Reproduction:

const http = require("node:http");
const axios = require("axios");

const server = http.createServer((req, res) => {
  req.on("error", (e) => {
    console.error("http.IncomingMessage error", e);
  });
  res.on("error", (e) => {
    console.error("http.ServerResponse error", e);
  });

  setTimeout(() => {
    res.end();
    res.socket.destroy();
  }, 50);
});

async function main() {
  await new Promise((resolve) => server.listen(resolve));
  const endpoint = "http://127.0.0.1:" + server.address().port;
  console.log("Server listening:", endpoint);

  const bigBody = Buffer.alloc(10 * 1024 * 1024, "a");
  const res = await axios.post(endpoint, bigBody, {
    // The fetch adapter does not cause a crash
    // adapter: 'fetch',
  });

  // Add this event listener to avoid crashing the process
  // res.request.socket.on("error", (err) => {
  //   console.log("I think Axios should've handled this:", err);
  // });

  console.log({
    status: res.status,
    statusText: res.statusText,
    data: res.data,
  });

  server.close();
}

main().catch((e) => {
  console.error("This is what we want, a normal promise rejection", e);
  process.exit(0);
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    issue::performanceThis issue is related to addressing performance related issuespriority::mediumA medium priority

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions