Introduction

Axios in Node.js can fail in a confusing way when the request body is a stream, form-data instance, or another object that Axios expects to measure before sending. A common failure path is around data.getLength(...) in the Node HTTP adapter. Instead of a clean application error, the request may hang, abort, or surface an unhelpful stack trace depending on the Axios version and the payload helper you used.

Symptoms

  • Requests fail only in Node.js, not in the browser
  • Multipart uploads hang or terminate before the request is fully sent
  • Stack traces mention getLength, form-data, or the Axios HTTP adapter
  • The issue appears after switching payload libraries or upgrading Axios

Common Causes

  • A payload object is not a real form-data instance even though Axios treats it like one
  • form-data cannot calculate content length for one of the appended values
  • Headers from form.getHeaders() were not merged into the Axios request
  • A custom stream or buffer wrapper does not expose the shape Axios expects

Step-by-Step Fix

  1. 1.Confirm the payload type before Axios sends it
  2. 2.Check whether the request body is actually a form-data object with the methods Axios expects.

```javascript import FormData from "form-data";

const form = new FormData(); form.append("file", fs.createReadStream("./upload.bin"));

console.log(form instanceof FormData); console.log(typeof form.getLength, typeof form.getHeaders); ```

  1. 1.Calculate content length explicitly
  2. 2.If length resolution is the failing step, call it yourself so you can see the real error instead of a vague adapter failure.

```javascript form.getLength((error, length) => { if (error) { console.error("getLength failed", error); return; }

console.log("content-length", length); }); ```

  1. 1.Pass multipart headers and avoid mixed payload helpers
  2. 2.Do not combine browser FormData assumptions with Node form-data behavior.

```javascript const headers = form.getHeaders();

const response = await axios.post("https://api.example.com/upload", form, { headers, maxBodyLength: Infinity, }); ```

  1. 1.Fall back to a buffered upload when length detection is unreliable
  2. 2.For some integrations, using a buffer with explicit headers is simpler and more stable than dynamic length detection.

```javascript const body = fs.readFileSync("./upload.bin");

await axios.post("https://api.example.com/upload", body, { headers: { "content-type": "application/octet-stream", "content-length": body.length, }, }); ```

Prevention

  • Use one multipart library consistently in Node.js code paths
  • Log payload type and headers before investigating Axios adapter internals
  • Test uploads with the exact runtime version of Axios used in production
  • Prefer explicit content length when the upstream requires strict request framing