{"record":{"id":"aee05f8410a36457","repo":"remix-run/remix","slug":"multipart-boundary-exceeds-maximum-length-of-max","errorCode":null,"errorMessage":"Multipart boundary exceeds maximum length of ${maxBoundaryLength} characters","messagePattern":"Multipart boundary exceeds maximum length of (.+?) characters","errorType":"validation","errorClass":"MultipartParseError","httpStatus":null,"severity":"error","filePath":"packages/multipart-parser/src/lib/multipart.ts","lineNumber":262,"sourceCode":"  #findPartialTailBoundary: PartialTailSearchFunction\n  #boundaryLength: number\n  #boundaryBytes: Uint8Array\n\n  #state = MultipartParserStateStart\n  #buffer: Uint8Array | null = null\n  #currentHeader: Uint8Array | null = null\n  #currentContent: Uint8Array[] | null = null\n  #contentLength = 0\n  #partCount = 0\n  #totalContentLength = 0\n\n  /**\n   * @param boundary The boundary string used to separate parts\n   * @param options Options for the parser\n   */\n  constructor(boundary: string, options?: MultipartParserOptions) {\n    if (boundary.length > maxBoundaryLength) {\n      throw new MultipartParseError(\n        `Multipart boundary exceeds maximum length of ${maxBoundaryLength} characters`,\n      )\n    }\n\n    this.boundary = boundary\n    this.maxHeaderSize = options?.maxHeaderSize ?? 8 * oneKb\n    this.maxFileSize = options?.maxFileSize ?? 2 * oneMb\n    this.maxParts = options?.maxParts ?? defaultMaxParts\n    this.maxTotalSize =\n      options?.maxTotalSize ?? this.maxFileSize * defaultMaxTotalSizePartAllowance + oneMb\n\n    this.#findOpeningBoundary = createSearch(`--${boundary}`)\n    this.#openingBoundaryLength = 2 + boundary.length // length of '--' + boundary\n    let boundaryPattern = `\\r\\n--${boundary}`\n    this.#findBoundary = createSearch(boundaryPattern)\n    this.#findPartialTailBoundary = createPartialTailSearch(boundaryPattern)\n    this.#boundaryLength = 4 + boundary.length // length of '\\r\\n--' + boundary\n    this.#boundaryBytes = encodeAsciiPattern(boundaryPattern)","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/multipart-parser/src/lib/multipart.ts#L244-L280","documentation":"The MultipartParser constructor rejects boundaries longer than the RFC 2046 limit (maxBoundaryLength, 70 characters). Oversized boundaries are almost always a symptom of malformed input or a corrupted header, so construction fails fast instead of mis-parsing.","triggerScenarios":"new MultipartParser(boundary) where boundary.length exceeds 70 characters; or parseMultipartRequest/parseMultipartStream deriving such a boundary from a Content-Type header with a huge boundary value.","commonSituations":"Malicious or fuzzed requests with inflated boundary parameters; copy-paste errors embedding whitespace/base64 blobs into the boundary; hand-written test fixtures with arbitrary long delimiters.","solutions":["Reject or truncate requests whose boundary parameter exceeds 70 characters before parsing (a 4xx response is appropriate)","Regenerate the boundary with a standard short random value (e.g. crypto.randomUUID() based)","Fix test fixtures to use realistic boundaries"],"exampleFix":"// before\nnew MultipartParser('x'.repeat(200))\n\n// after\nlet boundary = `----node${crypto.randomUUID()}`\nnew MultipartParser(boundary)","handlingStrategy":"validation","validationCode":"const MAX_BOUNDARY = 70\nif (boundary.length > MAX_BOUNDARY) {\n  throw new Response(`Boundary too long (max ${MAX_BOUNDARY})`, { status: 400 })\n}","typeGuard":null,"tryCatchPattern":"try {\n  new MultipartParser(boundary)\n} catch (error) {\n  if (error instanceof MultipartParseError && error.message.includes('maximum length')) {\n  return new Response('Invalid multipart boundary', { status: 400 })\n  }\n  throw error\n}","preventionTips":["Generate boundaries from short random values (UUID-based), never user input","Validate boundary length before constructing the parser"],"tags":["multipart","boundary","rfc-2046","validation"],"backgroundTag":"multipart-boundary-invalid","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}