Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Multipart Upload Progress and Retry Boundaries

Last updated: 5 Oct 20266 min read
tutorial
IntermediateBy AITrove Editorial

Selecting a file does not upload it, completing a network transfer does not prove the server accepted it, and showing a preview does not prove it is safe to serve later. A browser form can send a file with multipart/form-data. When constructing FormData for fetch, let the browser set the Content-Type header so it includes the correct boundary; a hand-written multipart header without that boundary breaks parsing. Progress reporting requires an API or upload protocol that exposes transferred bytes. A large-file resume feature needs an explicit upload ID, chunk positions, integrity checks, expiry, and finalization step on the server.

Working case

The intake form accepts a 47 MB inspection video. A developer shows 'Uploaded' as soon as the browser has sent all bytes, but the server later rejects the file after validation. Change the states to Selected, Transferring, Processing, Accepted, or Rejected. For a small file, one multipart request may be enough. For larger files on unstable connections, split into bounded chunks only if the server supports session ownership and idempotent chunk retries. A cancelled upload must release on-device preview URLs and tell the server to expire or discard unfinished data.

Implementation boundary

javascript
async function sendEvidence(formElement, endpoint) {
  const payload = new FormData(formElement);
  const response = await fetch(endpoint, { method: "POST", body: payload });
  if (!response.ok) throw new Error("Evidence was not accepted");
  return response.json();
}

The browser adds the multipart boundary when given FormData; do not set that Content-Type manually. The server still checks authorization, size, media type from inspected bytes, storage quotas, and malware policy before attaching a file to a case. Fetch does not provide a simple cross-browser upload progress event through this pattern, so a product requiring byte progress needs a supported transport or a separate chunk protocol. Retrying a complete one-shot POST can duplicate the file unless the server uses a stable request identity. Keep the upload's temporary ID scoped to the account and case.

Cost and boundaries

A single multipart transfer costs O(b) bytes for a file of size b, plus protocol overhead; building large blobs in JavaScript can add O(b) memory on top of the browser's file handle. Chunking with c-byte parts adds roughly O(b/c) requests and metadata operations, but permits bounded retry of a failed part. Each server-side temporary object consumes storage until accepted or expired. Select thresholds from measured network conditions and server limits, and do not add a resume protocol to a form that only accepts tiny attachments.

Failure trace

The client sets Content-Type: multipart/form-data by hand, omitting the boundary; the server reports an empty file even though the browser sent bytes. Remove that header and let FormData control it. A second failure occurs when the server returns 202 for processing and the UI calls the upload Accepted immediately. Wait for final validation or show Processing with a status check. If a chunk retry arrives twice, the server must recognize the same upload ID and byte range rather than appending duplicate bytes.

Verification

  • Multipart requests include a browser-generated boundary.
  • Transfer completion does not imply server acceptance.
  • A repeated chunk cannot duplicate bytes or attach a file twice.

Practice drill

Submit a small file using a native form and FormData, then inspect the request boundary in developer tools. Break the manually set header in a controlled branch and confirm the server refuses it. For a simulated large file, interrupt the third chunk, retry the same range, and verify the final byte length and checksum. Reject the file after transfer and check that the interface says Rejected rather than Uploaded. Cancel midway and verify preview URL cleanup and temporary server-data expiry.

Decision note

Represent upload states honestly and introduce resumable chunks only with server-owned identity, integrity, and finalization.

Common Mistakes

  • Manually setting multipart Content-Type for FormData fetch.
  • Treating a on-device preview as a validated server asset.
  • Retrying a non-idempotent upload without a stable upload identity.

Connected lessons

Forms and Data Entry Workflows; Native Form Submission and Progressive Enhancement; Asynchronous Field Validation Races; Autosave, Draft Recovery, and Conflicts; Safe File Upload Pipeline; Idempotent Write Requests and Lost Responses; Browser Memory and Resource Lifecycles.

Apply and check

Build Project: recoverable case intake form and review Web Development: rendering and forms decisions quiz.

Further connections

Resumable Transfer Parts and Integrity.

web-tech
web-development
Storage details