nodejs/node · error · RequestContentLengthMismatchError
UND_ERR_REQ_CONTENT_LENGTH_MISMATCH
UND_ERR_REQ_CONTENT_LENGTH_MISMATCH
Error message
Request body length does not match content-length header
What it means
Thrown by writeBlob() in client-h1.js (HTTP/1.1) as RequestContentLengthMismatchError (code UND_ERR_REQ_CONTENT_LENGTH_MISMATCH). When the request body is a Blob, undici compares the declared content-length to body.size before writing; if they differ, the wire bytes would contradict the header, so it refuses to send a malformed request.
Source
Thrown at deps/undici/src/lib/dispatcher/client-h1.js:1554
abort(err)
}
}
/**
* @param {AbortCallback} abort
* @param {Blob} body
* @param {import('./client.js')} client
* @param {import('../core/request.js')} request
* @param {import('net').Socket} socket
* @param {number} contentLength
* @param {string} header
* @param {boolean} expectsPayload
* @returns {Promise<void>}
*/
async function writeBlob (abort, body, client, request, socket, contentLength, header, expectsPayload) {
try {
if (contentLength != null && contentLength !== body.size) {
throw new RequestContentLengthMismatchError()
}
const buffer = Buffer.from(await body.arrayBuffer())
socket.cork()
socket.write(`${header}content-length: ${contentLength}\r\n\r\n`, 'latin1')
socket.write(buffer)
socket.uncork()
request.onBodySent(buffer)
request.onRequestSent()
if (!expectsPayload && request.reset !== false) {
socket[kReset] = true
}
client[kResume]()
} catch (err) {View on GitHub (pinned to 1b2de5e052)
Solutions
- Do NOT set content-length manually for Blob/Buffer bodies — let undici compute it from body.size.
- If you must set it, ensure the value equals body.size exactly (same byte length).
- Recompute the length from the exact buffer you are about to send.
Example fix
// before
await client.request({ method: 'POST', path: '/', body: blob, headers: { 'content-length': '100' } }) // != blob.size
// after — let undici derive content-length
await client.request({ method: 'POST', path: '/', body: blob }) Defensive patterns
Strategy: validation
Validate before calling
function blobRequest(client, path, blob, headers = {}) {
delete headers['content-length'] // let undici derive from blob.size
if (blob.size !== undefined && headers['content-length'] !== undefined) {
if (Number(headers['content-length']) !== blob.size) throw new RangeError('content-length != blob.size')
}
return client.request({ method: 'POST', path, body: blob, headers })
} Type guard
const lengthMatchesBlob = (headers, blob) => headers['content-length'] == null || Number(headers['content-length']) === blob.size
Try / catch
try { await client.request(req) } catch (e) { if (e.code === 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH') { delete req.headers['content-length']; /* retry */ } else throw e } Prevention
- Never set content-length manually for Blob/Buffer bodies — undici computes it.
- Measure length from the exact buffer you send.
When it happens
Trigger: request({ method: 'POST', body: new Blob([...]), headers: { 'content-length': 'N' } }) where N !== blob.size; passing a content-length header that you computed against a different (mutated) blob.
Common situations: Hard-coding or caching a content-length value while the Blob is rebuilt asynchronously; a proxy/middleware that rewrites content-length; mutating the Blob's underlying buffer after size was measured.
Related errors
- UND_ERR_REQ_CONTENT_LENGTH_MISMATCH
- UND_ERR_INVALID_ARG
- UND_ERR_INVALID_ARG
- UND_ERR_INVALID_ARG
- UND_ERR_INVALID_RETURN_VALUE
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/2c69f700e783e7d0.
Report an issue: GitHub.