Repository navigation
Undocumented breaking change on v16.0.0 #38924
Description
Activity
- addedhttpIssues and PRs related to the http subsystem.Issues and PRs related to the http subsystem.
on Jun 4, 2021 I would guess that the
'close'event is specific to the request stream and not the underlying socket.From
http.IncomingMessageclosedocumentation:Event: 'close'
Added in: v0.4.2
Indicates that the underlying connection was closed.
So the (documented) intention is not that the stream was closed, but the underlying [socket] connection. That's still our documentation on v16, which makes me think this might've been an unintentional change. cc @nodejs/tsc @nodejs/http
The current behavior is correct per se and totally intentional to be compliant with streams. I would rather update the documentation which is wrong IMO.
The old behavior basically means that using it in a streams api is undefined behavior from the user’s perspective.
It needs to be both documented as a breaking change in our changelogs and the documentation needs to be updated then. Right now this is a breaking change that is not documented anywhere. In which PR was it introduced?
I just added a comment before here thinking this was a breaking change on a minor... 😳
Don't mind me...
Reacted by bl-ue, Matteo Collina and François-Marie de JouvencelReacted by bl-ueIf we don't find the PR which introduced the change, it might land soon by mistake on v14.x.
I’m pretty sure the Pr was semver. Can’t find it at the moment. Will look a bit more tonight.
Wait. This is on IncomingMessage which is a Readable. I’m very surprised if the behavior is different on node 14.
It might be doe autoDestroy true change we did.
It was only reverted on v15 and then made it into v16 as a semver major. I think the fix here is docs and maybe missing in change log.
Oh I see, it was actually landed initially as semver-minor.
Our release tooling is not capable of detecting that a change was retroactively marked major. I agree the fix is to update the docs (add a "changes" entry somewhere)Reacted by Robert Nagy and Zach BloomquistOur release tooling is not capable of detecting that a change was retroactively marked major.
It's not only about major changes. If something lands on
master, is released on some version, and is then reverted only on a release branch, the next major is not going to have this change in its changelog.Reacted by Matteo Collina, mary marchini and Zach Bloomquist- addeddocIssues and PRs related to Node.js documentation.Issues and PRs related to Node.js documentation.
on Jun 10, 2021 9 remaining items
I think nothing else is needed on this. Can we close the issue?
I don't think the docs and changelogs were updated with the new behavior yet (unless I missed it).
Oh, I missed that. I'll take care of it.
Just to clarify, the change is that onIncomingMessagethecloseevent is emitted when a HTTP request is finished and not (like in was in the past) when the underlying socket is closed. Am I right?Reacted by Robert Nagy- added a commit that references this issue
on Apr 1, 2022 - added a commit that references this issue
on Apr 25, 2022 - added a commit that references this issue
on May 31, 2022 - added a commit that references this issue
on Jun 27, 2022 - added a commit that references this issue
on Jul 11, 2022 - added a commit that references this issue
on Oct 10, 2022 I've just run into this as well (and this is not the only issue that has been opened for this exact breaking change). I'm using the
closeevent to abort anAbortControllerto cancel tasks (e.g. in a worker via Piscina) when the client stops the request (e.g. a "Cancel" button in the UIabort()s thefetchon the client, which propagates all the way and cancels the task on the server, similar toContextin Go).I don't think I can listen to
closeonsocket, because of HTTP/2 (a socket does not correlate to a single request/response cycle) or even just because ofKeep-Alivein HTTP/1.1? Where can I overrideautoDestroy, if at all (I'm using fastify)? Or is there any other reliable way to do what I'm doing in Node.js 16+?Edit: nvm, I guess listening for the socket close seems to do what I need with some tweaking.
@Prinzhorn What was the tweaking you did to make this working reliably?
@Fabioni I only needed this to work in a specific environment (Electron + HTTP/1.1). Take a look at the implementation of https://www.npmjs.com/package/fastify-racing for a more general approach
- added a commit that references this issue
on May 6, 2026
What steps will reproduce the bug?
index.jsand run it.curl localhost:8080How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
Prior to v16, the server would print the output below and hang.
What do you see instead?
On v16, the server prints the output below and hang.
On both cases curl doesn't exit while waiting for a response. Note that 2 is being called because
closeis being emitted even though the connection is not closed yet. I'm not sure if that is intended behavior or not, but I couldn't find anything in the changelog suggesting this was an intentional change. Furthermore, it's a breaking change and it should be documented as such.Additional information
The example above is an overly simplification of a situation I've stumbled upon while investigating failing restify tests on Node.js v16. The failing test in question is this, and the failure happens because restify expects close to only be called when the connection closes.