{"record":{"id":"a79460193348b4ff","repo":"remix-run/remix","slug":"exceeded-maximum-header-size","errorCode":null,"errorMessage":"Exceeded maximum header size","messagePattern":"Exceeded maximum header size","errorType":"exception","errorClass":"MaxHeaderSizeExceededError","httpStatus":null,"severity":"error","filePath":"packages/multipart-parser/src/lib/multipart.ts","lineNumber":401,"sourceCode":"          break\n        }\n\n        index += 2 // Skip \\r\\n after boundary\n\n        this.#state = MultipartParserStateHeader\n      }\n\n      if (this.#state === MultipartParserStateHeader) {\n        if (chunkLength - index < 4) {\n          this.#buffer = chunk.subarray(index)\n          break\n        }\n\n        let headerEndIndex = findDoubleNewline(chunk, index)\n\n        if (headerEndIndex === -1) {\n          if (chunkLength - index > this.maxHeaderSize) {\n            throw new MaxHeaderSizeExceededError(this.maxHeaderSize)\n          }\n\n          this.#buffer = chunk.subarray(index)\n          break\n        }\n\n        if (headerEndIndex - index > this.maxHeaderSize) {\n          throw new MaxHeaderSizeExceededError(this.maxHeaderSize)\n        }\n\n        this.#currentHeader = chunk.subarray(index, headerEndIndex)\n        this.#currentContent = []\n        this.#contentLength = 0\n\n        index = headerEndIndex + 4 // Skip header + \\r\\n\\r\\n\n\n        this.#state = MultipartParserStateBody\n","sourceCodeStart":383,"sourceCodeEnd":419,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/multipart-parser/src/lib/multipart.ts#L383-L419","documentation":"While scanning for the \\r\\n\\r\\n that terminates a part's headers, the parser buffers the pending bytes; if the buffered header region grows beyond maxHeaderSize without finding the double newline, it throws MaxHeaderSizeExceededError. This guards against unbounded memory use from header-flood or malformed parts.","triggerScenarios":"A multipart part whose headers never contain \\r\\n\\r\\n within maxHeaderSize bytes — e.g. a part with thousands of header lines, extremely long single header values, or binary body data mistaken for headers after a missed boundary.","commonSituations":"Legitimate clients attaching very large custom headers or metadata per part; malicious header flooding; a wrong boundary causing the parser to interpret body bytes as header bytes.","solutions":["If headers are legitimately large, pass a larger maxHeaderSize in MultipartParserOptions (default 8 KB)","Audit clients for unnecessary per-part headers and trim them","If unexpected, verify the boundary matches the actual body delimiters — a mismatch makes body data parse as headers"],"exampleFix":"// before\nlet parts = parseMultipartRequest(request) // default 8KB header limit\n\n// after\nlet parts = parseMultipartRequest(request, { maxHeaderSize: 64 * 1024 })","handlingStrategy":"validation","validationCode":"// pre-check declared header size when possible\nlet declared = Number(request.headers.get('Content-Length') ?? 0)\nif (declared > 10 * 1024 * 1024) return new Response('Payload too large', { status: 413 })\n// and parse with an explicit, adequate limit:\nparseMultipartRequest(request, { maxHeaderSize: 64 * 1024 })","typeGuard":null,"tryCatchPattern":"try {\n  for await (let part of parseMultipartRequest(request)) { /* ... */ }\n} catch (error) {\n  if (error instanceof MaxHeaderSizeExceededError) {\n    return new Response('Part headers too large', { status: 413 })\n  }\n  throw error\n}","preventionTips":["Configure maxHeaderSize to match your clients' real per-part headers","Discourage per-part metadata headers; move metadata into body fields"],"tags":["multipart","headers","limits","dos-protection"],"backgroundTag":"multipart-header-limit-exceeded","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}