#4405·undici

Process does not exit after aborting a request to an unresponsive host

Author: rednebCreated Aug 12, 2025Updated Aug 31, 2026
Labelsbug

Bug Description

When issuing an HTTP request to an unresponsive host with undici and aborting it via AbortController before the library’s timeout elapses, the request rejects as expected, but the Node.js process remains alive until the original timeout completes. With no other work pending, the process should exit promptly after the abort.

Reproducible By

Use the following minimal script as test.mjs:

javascript
import {fetch} from "undici";

const url = "http://1.2.4.5:6789/"; // no server expected

const controller = new AbortController();
setTimeout(() => {
  console.log(new Date().toISOString(), "aborting");
  controller.abort();
}, 1000).unref();

fetch(url, {signal: controller.signal})
  .catch(() => {})
  .then(() => {
    console.log(new Date().toISOString(), "fetch finished");
  });

Then run with a wrapper to show process lifetime:

bash
printf '%s before\n' "$(date -uIs)"; node test.mjs; printf '%s after\n' "$(date -uIs)"

Observed result: the request is aborted quickly, but the process does not exit until around the default connect/overall timeout.

Expected Behavior

After AbortController.abort() causes the fetch to reject, and with no other referenced timers/handles, the process should exit immediately (or very shortly thereafter).

Logs & Screenshots

2025-08-12T10:56:55+00:00 before
2025-08-12T10:56:56.412Z aborting
2025-08-12T10:56:56.416Z fetch finished
2025-08-12T10:57:05+00:00 after

Note: “after” prints ~10s after the request was aborted/settled, suggesting an internal referenced timer/handle remains until timeout expiry.

Environment

  • OS: Linux 6.12.36
  • Node.js: v22.13.1
  • undici: 7.13.0

Additional context

It appears an internal connect/overall timeout or connection attempt remains referenced after abort, keeping the event loop alive until timeout expiry.