Skip to content

HTTP/1.1 server aborts upload request in Node.js 18 #47421

@nwtgck

Description

@nwtgck

Version

18.0.0, 18.15.0

(14.21.3, 16.20.0, 17.9.1 works fine)

Platform

GitHub Actions ubuntu-20.04

Here is uname -a:

Linux fv-az222-460 5.15.0-1034-azure #41~20.04.1-Ubuntu SMP Sat Feb 11 17:02:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

http

What steps will reproduce the bug?

First of all, it is a super strange bug but I made a simple code for reproducing it.

Here is the whole code:
nwtgck/public-code@02b852b...6f51243

Run the following code by node server1.js. The server consumes the request body, responds "Finished!" and ends when the request body is read.

// server.js
const http = require("http");

const server = http.createServer((req, res) => {
  console.log(`${req.method} ${req.url}`);
  req.on("data", (data) => console.log(`on data: ${data.length}B`));
  req.on("close", () => console.log("req closed"));
  req.on("aborted", () => console.log("req aborted"));
  req.on("error", (err) => console.log("req error", err));
  req.on("end", () => {
    console.log("req end");
    res.end("Finished!\n");
  });
  res.writeHead(200);
  res.write("Handling...\n");
});

server.listen(3000, () => {
  console.log(`Listening on ${server.address().port}...`);
});

Upload a text sequence of 1-100 with 10 byte limit as follows.

seq 100 | pv -L 10 | curl -sST- http://127.0.0.1:3000

After approximately 23~26 seconds, the curl stops suddenly.

Here is the server-side stdout which outputs ECONNRESET error.

...
on data: 1B
on data: 1B
req aborted
req error Error: aborted
    at connResetException (node:internal/errors:717:14)
    at abortIncoming (node:_http_server:754:17)
    at socketOnClose (node:_http_server:748:3)
    at Socket.emit (node:events:525:35)
    at TCP.<anonymous> (node:net:322:12) {
  code: 'ECONNRESET'
}
req closed

How often does it reproduce? Is there a required condition?

Use GitHub Actions to reproduce it. My local Ubuntu 20.04 actual machine, GitHub Codespace, M1 Mac and Vagrant on Intel Mac did not reproduce it.

GitHub Actions (without sleep 300)

Here is the result:

  • Node 14.12.3: 0/10 failed
  • Node 16.20.0: 0/10 failed
  • Node 17.9.1: 0/10 failed
  • Node 18.0.0: 8/10 failed
  • Node 18.15.0: 9/10 failed

The result means Node 14-17 works but Node 18 does not work more than 80%.

The result was created by re-run GitHub Actions 10 times:
image
https://github.com/nwtgck/public-code/actions/runs/4602240359

GitHub Actions (with sleep 300)

Here is the super strange part. I added 5-minite wait and the server on Node 18 works fine. Both Node 18.0.0 and 18.15.0 worked well 10 times (0/10 failed).

All I did is adding sleep 300 at the very begining before checkout:

image

nwtgck/public-code@04d99e2

(whole code: nwtgck/public-code@02b852b...04d99e2)

The sleep-result was also created by re-run GitHub Actions 10 times:
image
https://github.com/nwtgck/public-code/actions/runs/4602334265

What is the expected behavior? Why is that the expected behavior?

The expected behavior is curl uploading successfully:

$ seq 100 | pv -L 10 | curl -sST- http://127.0.0.1:3000
Handling...
Finished!

Additional information

I confirmed CircleCI also has the same issue before simplifying a reproducing code. machine.image is ubuntu-2004:2023.02.1 and ubuntu-2004:202010-01. I will create a simple CircleCI reproducing code If a Node.js member needs it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    httpIssues or PRs related to the http subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions