Description
Version
18.12.1
Platform
Client host: Microsoft Windows NT 10.0.22631.0 x64
Server host: Linux WILL 6.1.55+g98dbb77667fc #1 SMP PREEMPT Tue Nov 21 23:45:58 UTC 2023 aarch64 GNU/Linux
Subsystem
No response
What steps will reproduce the bug?
PC running Node app (v18.12.1) creates an http.request with the following configuration:
const stream = fs.createReadStream(filePath);
const options = {
hostname: ip,
port: 9898,
path: '/path/to/upload',
method: 'POST',
agent: false,
headers: {
'Content-Type': 'application/octet-stream',
'Transfer-Encoding': 'chunked',
'Content-Disposition': `attachment; filename="${filename}"`,
'x-var': 2000
}
};
const request = http.request(options, (res) => {
console.log(`Status message is: ${res.statusMessage}`);
console.log(`Status Code is: ${res.statusCode}`);
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => { ... });
});
fileStream.pipe(request);
fileStream.on('data', (chunk) => { ... });
fileStream.on('end', () => { request.end(); })
Linux device running node app (v18.17.1) on the same LAN creates an Express server and configures the endpoint:
app.post('/path/to/upload' async (req, res) => {
req.setTimeout(0);
const content = req.headers['content-disposition'];
const name = contentDisposition.match(/filename="(.+"/);
const suggest = name ? name[1] : 'received-file.txt';
const filePath = path.join(this.systemPath , suggest);
let amount = parseInt(req.headers['x-var']);
try {
const chunks = await new Promise((resolve, reject) => {
let chunks = [];
req.on('data', (chunk) => { chunks.push(chunk); })
req.on('end', () => {
res.status(202).json({ message: "success" });
resolve(Buffer.concat(chunks)
});
// Server sends back a 408 to the client then enters this block
req.on('error', () => {
return res.status(500).json({ message: `File transfer failure. Please try again.` })
});
catch { ... }
})
Error stack trace:

Sometimes, it's slightly different:
Status Code is: 408
An error occurred: Error: write ECONNRESET
at afterWriteDispatched (node:internal/stream_base_commons:160:15)
at writeGeneric (node:internal/stream_base_commons:151:3)
at Socket._writeGeneric (node:net:917:11)
at Socket._write (node:net:929:8)
at doWrite (node:internal/streams/writable:411:12)
at clearBuffer (node:internal/streams/writable:572:7)
at Writable.uncork (node:internal/streams/writable:351:7)
at connectionCorkNT (node:_http_outgoing:898:8)
at process.processTicksAndRejections (node:internal/process/task_queues:81:21)
{ errno: -4077, code: 'ECONNRESET', syscall: 'write' }
Wireshark packet capture shows [RST, ACK] being issued from server -> client.
How often does it reproduce? Is there a required condition?
Reproducible about <1% of the time when attempting a file upload of about 220 MB.
What is the expected behavior? Why is that the expected behavior?
Wondering if this actually is expected behavior from TCP or if it's an issue at the Node application level. If it is TCP, what workarounds to implement, besides a retry mechanism?
What do you see instead?
Status Code is: 408
An error occurred: Error: write ECONNRESET
at afterWriteDispatched (node:internal/stream_base_commons:160:15)
at writeGeneric (node:internal/stream_base_commons:151:3)
at Socket._writeGeneric (node:net:917:11)
at Socket._write (node:net:929:8)
at doWrite (node:internal/streams/writable:411:12)
at clearBuffer (node:internal/streams/writable:572:7)
at Writable.uncork (node:internal/streams/writable:351:7)
at connectionCorkNT (node:_http_outgoing:898:8)
at process.processTicksAndRejections (node:internal/process/task_queues:81:21)
{ errno: -4077, code: 'ECONNRESET', syscall: 'write' }
Additional information
No response