· via dev.to (home feed)
CVE-2026-109869 lets remote servers crash Node.js fetch via orphaned undici stream
A CVSS 7.5 flaw in undici, Node.js's default fetch client, lets any server it contacts crash the process with more than five Content-Encoding headers and an early disconnect; fixed in 6.29.1, 7.30.1 and 8.12.2.

High-severity DoS bug in undici's fetch
A denial-of-service vulnerability tracked as CVE-2026-109869 (GHSA-xjj6-f33q-929c) allows any HTTP server that a Node.js application contacts to kill the entire process, according to a CVE report published on dev.to. The flaw sits in undici, the HTTP/1.1 client and Fetch implementation that serves as Node.js's default fetch(). The report gives it a CVSS v3.1 score of 7.5 (High), with a network attack vector, no privileges or user interaction required, and impact confined to availability. The underlying weakness is classified under CWE-248 (uncaught exception) and CWE-459 (incomplete cleanup). A proof of concept exists, though the report notes the EPSS score is low at 0.343 percent and the flaw is not listed in CISA's Known Exploited Vulnerabilities catalog.
How the crash happens
The trigger is a response containing more than five Content-Encoding directives, sent by a server that then closes the connection before transmitting the body. In affected versions, undici creates the internal Readable stream for the response body before validating the number of content encodings. When the check subsequently fails, undici rejects the fetch promise, but the already-allocated stream is left orphaned, with no error listener and no abort signal attached. If the socket drops at that moment, the resulting error is emitted on a stream the application never had a reference to. With nothing listening, Node.js treats it as an uncaught exception and exits.
The report stresses that this bypasses normal error handling: wrapping the fetch call in try/catch, or chaining a catch handler to the promise, covers the rejection path but not the orphaned stream. The five-encoding ceiling itself mirrors earlier hardening in other HTTP stacks, with the fix drawing comparison to similar limits in urllib3 (GHSA-gm62-xv2j-4w53) and curl (CVE-2022-32206).
The fix and affected versions
The patch on the v8.x/main branch (commit b5084c7) makes two changes: the Readable stream is no longer created until after the content-encoding limit is enforced, and the failure path calls controller.abort() rather than a plain reject(), so the request is torn down cleanly instead of leaking a live stream. Backports landed on the v7 branch (commit 07ded49) and the v6 branch (commit 1325a87).
According to the dev.to report, the affected ranges and their fixes are:
- undici 6.23.0 through versions below 6.29.1, fixed in 6.29.1
- undici 7.18.0 through versions below 7.30.1, fixed in 7.30.1
- undici 8.0.0 through versions below 8.12.2, fixed in 8.12.2
What to check and do
The report recommends running npm ls undici, or the yarn/pnpm equivalent, to surface every direct and transitive copy, then updating package manifests and lockfiles to a patched release on the matching major version. The subtlety is the runtime: Node.js bundles its own undici to power the global fetch(), so a clean dependency tree does not guarantee the built-in client is patched. Operators can check process.versions.undici to see which version the runtime carries, then update Node.js or override the global fetch with an explicitly patched undici package.
As interim mitigations for environments that cannot upgrade immediately, the report suggests restricting outbound HTTP requests to allowlisted upstream domains via egress controls, and normalizing responses through a forward proxy that blocks responses carrying excessive Content-Encoding headers. Post-patch, regression tests should confirm that responses with more than five encodings reject cleanly instead of crashing on a premature socket closure.
Why it matters
This bug turns every outbound fetch into a potential crash vector. Services that request URLs chosen or influenced by others, such as link previews, webhook consumers, scrapers and third-party API integrations, can be brought down by a single hostile or compromised upstream, and a full process exit takes every concurrent request with it. It also demonstrates a class of defect that ordinary defensive coding cannot reach, because the exception never crosses the promise boundary the developer controls. And since Node's built-in fetch is affected independently of the dependency tree, remediation means looking past package.json into the runtime itself. The fix is small and available across three release lines, so the practical path is simple: inventory undici everywhere, including inside Node, and upgrade.
- #node-js
- #security
- #undici
- #fetch
- #denial-of-service
- #vulnerability