Title: req.signal.aborted becomes true after request body parse / stream close in Node 24.18.0 · Issue #64390 · nodejs/node · GitHub
Open Graph Title: req.signal.aborted becomes true after request body parse / stream close in Node 24.18.0 · Issue #64390 · nodejs/node
X Title: req.signal.aborted becomes true after request body parse / stream close in Node 24.18.0 · Issue #64390 · nodejs/node
Description: Version v24.18.0 Platform Darwin Deniss-MacBook-Pro.local 25.5.0 Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:19 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T8122 arm64 Subsystem No response What steps will reproduce the bug? In Nod...
Open Graph Description: Version v24.18.0 Platform Darwin Deniss-MacBook-Pro.local 25.5.0 Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:19 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T8122 arm64 Subsystem No response W...
X Description: Version v24.18.0 Platform Darwin Deniss-MacBook-Pro.local 25.5.0 Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:19 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T8122 arm64 Subsystem No response W...
Opengraph URL: https://github.com/nodejs/node/issues/64390
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"req.signal.aborted becomes true after request body parse / stream close in Node 24.18.0","articleBody":"### Version\n\nv24.18.0\n\n### Platform\n\n```text\nDarwin Deniss-MacBook-Pro.local 25.5.0 Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:19 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T8122 arm64\n```\n\n### Subsystem\n\n_No response_\n\n### What steps will reproduce the bug?\n\nIn Node 24.18.0, `IncomingMessage.prototype.signal.aborted` becomes true after the incoming message body has finished parsing and the request stream closes, even though `req.aborted === false`. This makes `req.signal.aborted` unreliable for detecting actual client aborts.\n\n**Context**\n\n- Node version: v24.18.0\n- Environment: local dev, no reverse proxy\n- Framework: Express + body-parser\n- Route: PATCH /tables/1\n- Comparison: a separate GET route does not show the issue\n\n**Suggested reproduction steps**\n\n1. Start an Express server on Node 24.18.0\n2. Add middleware logging:\n- `req.aborted`\n- `req.complete`\n- `req.signal.aborted`\n- `req.socket.destroyed`\n3. Send a PATCH request with a JSON body\n4. Observe:\n- early middleware logs `signalAborted: false`\n- later the same request logs `signal.aborted: true`\n- `req.close `fires before `signal.aborted` becomes true\n\nCode to reproduce:\n```\n\n// repro.js\nimport express from \"express\";\nimport bodyParser from \"body-parser\";\n\nconst app = express();\napp.use(bodyParser.json());\n\napp.use((req, res, next) => {\n\tconsole.log(\"early middleware:\", {\n\t\turl: req.originalUrl,\n\t\tmethod: req.method,\n\t\taborted: req.aborted,\n\t\tcomplete: req.complete,\n\t\tsignalAborted: req.signal.aborted\n\t});\n\n\treq.once(\"close\", () => {\n\t\tconsole.log(\"req close event\", req.originalUrl, {\n\t\t\taborted: req.aborted,\n\t\t\tsignalAborted: req.signal.aborted\n\t\t});\n\t});\n\n\tnext();\n});\n\napp.patch(\"/tables/1\", async (req, res) => {\n\tconsole.log(\"route start:\", {\n\t\taborted: req.aborted,\n\t\tsignalAborted: req.signal.aborted\n\t});\n\n\tawait new Promise((resolve) => setTimeout(resolve, 200));\n\n\tconsole.log(\"route before res send\", {\n\t\taborted: req.aborted,\n\t\tsignalAborted: req.signal.aborted\n\t});\n\n\tres.json({ ok: true });\n});\n\napp.listen(3009, () => {\n\tconsole.log(\"listening on 3009\");\n});\n\n```\n\n### How often does it reproduce? Is there a required condition?\n\nReproduces with PATCH requests that have a JSON body.\n\n### What is the expected behavior? Why is that the expected behavior?\n\n`req.signal.aborted` should only become `true` when the client aborts the request (transport-level cancellation before or during request processing), not when the incoming message handling completes normally or when body parsing ends.\n\n### What do you see instead?\n\nFor a normal PATCH request with a body:\n\n- early request logs show `signalAborted: false`\n- request body parsing completes successfully\n- `req.close` triggers\n- later, `req.signal.aborted` becomes true\n- `req.aborted` remains false\n\nKey evidence\n\n- `req.close` event in route handler is logged before the route observes `signal.aborted === true`\n- `req.aborted` remains `false`\n- normal cURL request reproduces it\n- the same request type in a different route does not reproduce it\n\nThis means the new signal.aborted property is firing on request stream completion/closure rather than on genuine abort.\n\n### Additional information\n\n**Why this is a bug**\n\nThe new `req.signal `API is supposed to expose request cancellation state. If it becomes true after normal request completion or stream close, it is effectively useless for distinguishing real client aborts. This appears to be the Node HTTP internals abort signal being fired when the request handling completes, rather than when the client actually aborts. That behavior breaks the use case of `req.signal.aborted` for client abort detection.","author":{"url":"https://github.com/dnorrstrand","@type":"Person","name":"dnorrstrand"},"datePublished":"2026-07-09T11:37:53Z","url":"https://github.com/nodejs/node/issues/64390"}
| react-profiling | 0 |
| react-import-map | react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@d5750093facf |
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:13519660-08ee-81fc-47e9-5ceedb4f66ad |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | C27C:22CA14:58CA6C:730914:6AED28B7 |
| html-safe-nonce | 9c23d2a3f7f440cc8bf8235fa087dda86be2b6ed68ae2364dd52df678c72b6a5 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDMjdDOjIyQ0ExNDo1OENBNkM6NzMwOTE0OjZBRUQyOEI3IiwidmlzaXRvcl9pZCI6Ijc1NjUwNTYwNzU4NDk2MDczNTEiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 0a6dba3e5a1e0557dbea570bb48e6fc0b7af1db67c7b06afdcd8f06a66c76363 |
| hovercard-subject-tag | issue:4845878042 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node/64390/issue_layout |
| twitter:image | https://opengraph.githubassets.com/098bfa877a058e34c2267fe80e9b8d88f94d157073da21dcfc5b0ebb5fc88fec/nodejs/node/issues/64390 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/098bfa877a058e34c2267fe80e9b8d88f94d157073da21dcfc5b0ebb5fc88fec/nodejs/node/issues/64390 |
| og:image:alt | Version v24.18.0 Platform Darwin Deniss-MacBook-Pro.local 25.5.0 Darwin Kernel Version 25.5.0: Mon Apr 27 20:41:19 PDT 2026; root:xnu-12377.121.6~2/RELEASE_ARM64_T8122 arm64 Subsystem No response W... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | dnorrstrand |
| hostname | github.com |
| expected-hostname | github.com |
| None | 9d95365dda0576efe9b71f45807595e396bd0ca9286fba5367a05048e6ddf8f2 |
| turbo-cache-control | no-preview |
| go-import | github.com/nodejs/node git https://github.com/nodejs/node.git |
| octolytics-dimension-user_id | 9950313 |
| octolytics-dimension-user_login | nodejs |
| octolytics-dimension-repository_id | 27193779 |
| octolytics-dimension-repository_nwo | nodejs/node |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 27193779 |
| octolytics-dimension-repository_network_root_nwo | nodejs/node |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 98b41fa4b5635ceb45a4c54320fced73817ff290 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
| react-app-name | issues |
Links:
Viewport: width=device-width