nodejs/node · error · RequestAbortedError

UND_ERR_ABORTED

UND_ERR_ABORTED

Error message

Response size (${contentLength}) larger than maxSize (${this.#maxSize})

What it means

Thrown at runtime by the dump interceptor's `onResponseStart` (a `RequestAbortedError`, code `UND_ERR_ABORTED`) when the response's `content-length` header exceeds the configured `maxSize`. Unlike the constructor validation, this fires during an actual request once the server's headers arrive: the interceptor refuses to buffer a body it knows will overflow the cap and aborts the request instead. This protects memory from oversized responses.

Source

Thrown at deps/undici/src/lib/interceptor/dump.js:41

  }

  #abort (reason) {
    this.aborted = true
    this.reason = reason
  }

  onRequestStart (controller, context) {
    controller.abort = this.#abort.bind(this)
    this.#controller = controller

    return super.onRequestStart(controller, context)
  }

  onResponseStart (controller, statusCode, headers, statusMessage) {
    const contentLength = headers['content-length']

    if (contentLength != null && contentLength > this.#maxSize) {
      throw new RequestAbortedError(
        `Response size (${contentLength}) larger than maxSize (${
          this.#maxSize
        })`
      )
    }

    if (this.aborted === true) {
      return true
    }

    return super.onResponseStart(controller, statusCode, headers, statusMessage)
  }

  onResponseError (controller, err) {
    if (this.#dumped) {
      return
    }

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Raise `maxSize`/`dumpMaxSize` to comfortably exceed the largest expected `content-length`.
  2. Remove the dump interceptor from code paths that legitimately stream large bodies.
  3. Handle the abort in a try/catch around `fetch`/`request` and fall back to a streaming read without the dump interceptor.
  4. If the size is genuinely unexpected (server returning a huge error page), treat the abort as a signal to inspect the upstream response.

Example fix

// before
new Agent().compose([dump()]) // default maxSize 1 MiB
await agent.request({ origin, path, method: 'GET' }) // server sends 5 MiB

// after
new Agent().compose([dump({ maxSize: 16 * 1024 * 1024 })]) // 16 MiB cap
await agent.request({ origin, path, method: 'GET' })
Defensive patterns

Strategy: try-catch

Validate before calling

function dumpMaxSizeFor(expectedMaxBytes) {
  // size the dump cap above the largest legitimate content-length
  return Math.max(1024 * 1024, Math.ceil(expectedMaxBytes * 1.5))
}

Try / catch

try {
  await agent.request({ method: 'GET', origin, path })
} catch (err) {
  if (err.code === 'UND_ERR_ABORTED' && /larger than maxSize/.test(err.message)) {
    // server sent more than dumpMaxSize; re-issue without the dump interceptor
    // or raise maxSize and retry
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: A server responds with `content-length: 10485760` (10 MiB) while `maxSize` is 1 MiB (the default). The check is `contentLength != null && contentLength > this.#maxSize`. The guard only fires when `content-length` is present — chunked/unknown-length responses are checked byte-by-byte later (`onResponseData` accumulates `#size`).

Common situations: Downloading files through an interceptor pipeline that includes dump; pointing a dump-instrumented client at an endpoint that returns large JSON/HTML; forgetting that the default cap is only 1 MiB; legitimate large payloads (media, logs) hitting an instrumentation interceptor.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/a7bdfe16b357056f. Report an issue: GitHub.