denoland/deno · error · TypeError
Multipart part has too many headers
Error message
Multipart part has too many headers
What it means
Thrown while parsing a single multipart part when the number of headers in that part exceeds MAX_MULTIPART_PART_HEADER_COUNT (128, ext/fetch/21_formdata.js:394). This is a resource-exhaustion guard (CVE-class hardening): a malicious part with thousands of header lines would otherwise burn CPU/memory in #parseHeaders().
Solutions
- If you control the client, fix the generator so each part carries only Content-Disposition (and Content-Type for files).
- On public servers, cap the accepted body size before parsing and return 413, so this parser limit is rarely reached.
- Treat this error as a 400 Bad Request: wrap formData() in try/catch and respond with 400 for TypeError from the parser.
Example fix
// before
const form = await request.formData(); // may throw on hostile input
// after
let form;
try {
form = await request.formData();
} catch (e) {
if (e instanceof TypeError) return new Response("malformed form data", { status: 400 });
throw e;
} Defensive patterns
Strategy: try-catch
Try / catch
try { form = await request.formData(); } catch (e) { if (e instanceof TypeError && /too many headers|form data/i.test(e.message)) return new Response("malformed multipart", { status: 400 }); throw e; } Prevention
- Treat multipart parsing of untrusted requests as fallible; always catch TypeError and map to 400.
- Cap request body sizes at the server/proxy layer.
- Keep part headers minimal (Content-Disposition, Content-Type only).
When it happens
Trigger: `await request.formData()` where one part's header block (lines containing ':') has more than 128 header lines. Legitimate browsers send 1-3 headers per part (Content-Disposition, Content-Type), so >128 indicates abuse or a broken generator.
Common situations: Fuzzed or hostile uploads against a public endpoint; a misbehaving client library that repeats the same header per line; denial-of-service attempts against formData() parsing.
Related errors
- Multipart part headers are too large
- Cannot construct MultipartParser: multipart/form-data must…
- Cannot turn into form data: missing boundary parameter in…
- Unable to parse body as form data
- Body can not be decoded as form data
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/070a6b88b76386be.
Report an issue: GitHub.
Appendix: source
Thrown at ext/fetch/21_formdata.js:436
}
/**
* @param {string} headersText
* @returns {{ headers: Headers, disposition: Map<string, string> }}
*/
#parseHeaders(headersText) {
const headers = new Headers();
const rawHeaders = StringPrototypeSplit(headersText, "\r\n");
let headerCount = 0;
for (let i = 0; i < rawHeaders.length; ++i) {
const rawHeader = rawHeaders[i];
const sepIndex = StringPrototypeIndexOf(rawHeader, ":");
if (sepIndex < 0) {
continue; // Skip this header
}
headerCount++;
if (headerCount > MAX_MULTIPART_PART_HEADER_COUNT) {
throw new TypeError("Multipart part has too many headers");
}
const key = StringPrototypeSlice(rawHeader, 0, sepIndex);
const value = StringPrototypeSlice(rawHeader, sepIndex + 1);
headers.set(key, value);
}
const disposition = parseContentDisposition(
headers.get("Content-Disposition") ?? "",
);
return { headers, disposition };
}
/**
* @param {number} index
* @returns {boolean}
*/
#matchesBoundary(index) {View on GitHub (pinned to 9ad36f7a2c)