Skip to content

http: fix leaked error listener on sync HTTP req create + destroy#62872

Open
pimterry wants to merge 2 commits intonodejs:mainfrom
pimterry:cleanup-freed-insta-destroy-socket-error-listener
Open

http: fix leaked error listener on sync HTTP req create + destroy#62872
pimterry wants to merge 2 commits intonodejs:mainfrom
pimterry:cleanup-freed-insta-destroy-socket-error-listener

Conversation

@pimterry
Copy link
Copy Markdown
Member

If you create a request and them immediately destroy it, a socket is created and then freed back to its agent (if there is one) next tick in onSocketNT, when we discover that the request is already gone before the socket is hooked up.

In that past that was fine, but in #61770 error handler setup was made synchronous, rather than waiting for next tick, to handle sync errors during request creation. Error handlers are cleaned up correctly if sockets are normally reused with agents, but not in the specific reuse-at-first-tick flow, because until now it wasn't required.

This change adds cleanup for that specific case. This doesn't leave any gap in error handler coverage - on 'free' the agent either synchronously adds its own error handler here or it assigns the socket to a request (going back to step one: setting up a new request error handler synchronously then initializing in onSocketNT) and we drop the leftover error handler immediately after that returns.

This PR also updates the docs to clarify when req.destroy() destroys the underlying socket: after onSocketNT, at which point we've hooked up the socket and may have started reading & writing for real. This matches existing behaviour going back many years, there's no recent change here and I think the behaviour is sane & expected, just making it explicit.

Previously, this resulted in an error listener being added but not
cleaned up when the socket was freed back to the agent pool.

This also updates the docs to clarify when req.destroy() kills the
underlying socket - only if it's called during request processing (more
specifically: after onSocketNT, at which point we may have started
reading & writing).

Signed-off-by: Tim Perry <pimterry@gmail.com>
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/http
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added http Issues or PRs related to the http subsystem. needs-ci PRs that need a full CI run. labels Apr 21, 2026
Comment thread test/parallel/test-http-client-request-listeners-leak.js
Comment thread test/parallel/test-http-client-request-listeners-leak.js Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.63%. Comparing base (a6e8368) to head (fee256b).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #62872   +/-   ##
=======================================
  Coverage   89.62%   89.63%           
=======================================
  Files         706      706           
  Lines      219140   219145    +5     
  Branches    41984    41981    -3     
=======================================
+ Hits       196415   196420    +5     
+ Misses      14618    14617    -1     
- Partials     8107     8108    +1     
Files with missing lines Coverage Δ
lib/_http_client.js 97.43% <100.00%> (+<0.01%) ⬆️

... and 34 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Signed-off-by: Tim Perry <pimterry@gmail.com>
@pimterry pimterry requested a review from lpinca April 21, 2026 16:15
@lpinca lpinca added request-ci Add this label to start a Jenkins CI on a PR. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Apr 21, 2026
@addaleax addaleax added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Apr 21, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 21, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

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

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. http Issues or PRs related to the http subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants