remix-run/remix · error · MaxPartsExceededError

Exceeded maximum number of parts

Error message

Exceeded maximum number of parts

What it means

Each time the parser starts a new part, #createPart increments a counter and throws MaxPartsExceededError when the count surpasses maxParts. This bounds how many parts a single request may contain, preventing part-count floods that would otherwise fit under size limits.

Source

Thrown at packages/multipart-parser/src/lib/multipart.ts:460

      return
    }

    if (this.#contentLength + chunk.length > this.maxFileSize) {
      throw new MaxFileSizeExceededError(this.maxFileSize)
    }

    if (this.#totalContentLength + chunk.length > this.maxTotalSize) {
      throw new MaxTotalSizeExceededError(this.maxTotalSize)
    }

    this.#currentContent!.push(chunk)
    this.#contentLength += chunk.length
    this.#totalContentLength += chunk.length
  }

  #createPart(): MultipartPart {
    if (++this.#partCount > this.maxParts) {
      throw new MaxPartsExceededError(this.maxParts)
    }

    return new MultipartPart(this.#currentHeader!, this.#currentContent!)
  }

  #analyzeCarryBoundary(
    carry: Uint8Array,
    chunk: Uint8Array,
  ): { kind: 'none' } | { kind: 'partial'; start: number } | { kind: 'full'; start: number } {
    let totalLength = carry.length + chunk.length

    for (let start = 0; start < carry.length; ++start) {
      let availableLength = totalLength - start
      let compareLength = Math.min(this.#boundaryLength, availableLength)

      let matched = true
      for (let i = 0; i < compareLength; ++i) {
        let sourceIndex = start + i

View on GitHub (pinned to 9696913134)

Solutions

  1. Raise maxParts in MultipartParserOptions if the form legitimately has many fields/files
  2. Reduce the number of parts the client sends (batch values into single fields)
  3. Catch MaxPartsExceededError and respond 413/400

Example fix

// before
parseMultipartRequest(request)

// after
parseMultipartRequest(request, { maxParts: 1000 })
Defensive patterns

Strategy: try-catch

Try / catch

try {
  for await (let part of parseMultipartRequest(request, { maxParts: PART_LIMIT })) { /* ... */ }
} catch (error) {
  if (error instanceof MaxPartsExceededError) {
    return new Response('Too many parts', { status: 413 })
  }
  throw error
}

Prevention

When it happens

Trigger: A multipart message with more parts than maxParts — many small form fields or many tiny files in one request.

Common situations: Clients appending hundreds/thousands of parts (e.g. per-chunk metadata), abuse via part flooding, or low default limits meeting legitimate multi-file forms.

Related errors


AI-assisted analysis of remix-run/remix@9696913134 (2026-08-27). Data as JSON: /api/errors/6b582448fb3e8b95. Report an issue: GitHub.