Infrastructure
S3 Multipart Upload Cleanup: Find Unfinished Storage
Inventory incomplete S3 multipart uploads, separate them from completed objects, choose safe age policies, and verify cleanup without disrupting active transfers.
In this article
An incomplete multipart upload is not the same thing as a completed object. Uploaded parts can remain after a client disappears or a workflow fails before completion. Track those uploads separately so storage cleanup does not depend only on the ordinary object listing.
AWS's multipart upload overview describes initiation, part transfer, completion, and abort behavior. Use the exact provider's documentation for an S3-compatible service; API similarity does not guarantee identical lifecycle rules, limits, or billing semantics.
Map the upload lifecycle
Record which component initiates the upload, retains its upload ID, sends parts, completes the object, and handles cancellation. An upload ID is an operational handle for a particular attempt, not a public authorization token or a permanent object identity.
Identify what happens when the browser closes, a worker crashes, or an access URL expires. A client-side failure message does not establish that the server has removed transferred parts. The workflow needs an explicit completion or cleanup decision based on observed state.
Keep successful object records separate from pending attempts. One intended object key can have retries or several initiated uploads. Avoid marking the product's file available until the supported completion operation and subsequent object checks succeed.
Inventory unfinished attempts
Use the provider's supported multipart-upload inventory or listing interface with authorized read-only access. Record bucket, key, upload ID, initiation time, and the owning workflow where available. An ordinary object list may not show the unfinished state you need.
Keep the report restricted if keys contain customer names or private project identifiers. Redact those values before sharing a diagnostic example. Storage metadata can be sensitive even when it contains no file body.
Group attempts by age and known ownership before proposing deletion. A long-running upload may still be legitimate for a particular product or network. Age is a useful signal, not sufficient proof that every old attempt is abandoned.
Set a policy from real transfer behavior
Determine the longest supported active upload and retry window. Include slow connections, resumable sessions, batch processing, and the application's recovery design. Choose an age threshold that leaves an appropriate buffer and document the reason.
For an invented example, a product allows an upload session to remain resumable for 24 hours. An immediate six-hour cleanup rule would conflict with that promise. The appropriate production threshold depends on the actual workflow, not this illustrative duration.
Review a lifecycle rule through the provider's supported configuration and change process. Scope it to the intended bucket or prefix where supported. Do not apply a broad account-wide cleanup policy just because a small test prefix accumulated unused parts.
Distinguish abort from object deletion
Aborting an unfinished upload and deleting a completed object are separate operations. The cleanup target should include the exact upload ID and key from the inspected inventory. A completed object under a similar key must remain untouched.
Check the documented behavior when parts are still being transferred. Cleanup may need coordination or subsequent verification. Do not assume that one successful abort response proves every concurrent activity and storage consequence has already settled.
Our S3 delete-marker guide concerns completed versioned objects. It is not a recovery plan for aborted multipart attempts. Preserve this distinction in support instructions so operators do not promise an unavailable restore path.
Test failures in a disposable prefix
Create approved synthetic uploads covering normal completion, explicit cancellation, lost client connection, and worker failure. Observe the actual pending inventory and subsequent cleanup. Use test data and explicit targets so the exercise cannot remove user files.
Verify that a completed object remains readable after the unfinished-attempt cleanup test. Also confirm an authorized active attempt inside the supported window can still resume and complete. Testing only that old parts disappear misses the risk of disrupting valid work.
Retain the provider response and object metadata. If the application reports success but the object is missing or incomplete, investigate completion and verification separately from the housekeeping policy.
Prevent recurrence in the application
Make the upload attempt a durable workflow record with an owner and last observed state. On cancellation or terminal failure, schedule the supported cleanup path within the application's existing execution system. Do not rely on a browser tab staying alive to finish server-side housekeeping.
Use safe retries for operations according to the provider's documented semantics. Reconcile actual storage state after a timeout before starting a new unrelated attempt. Otherwise retries can multiply pending uploads and make cost attribution harder.
Track unfinished age, count, and relevant storage cost through supported reports. Compare before and after the policy without inventing a fixed savings percentage. A lower count can be useful evidence while billing effects require their own measurement window.
CSV Viewer can inspect a redacted upload inventory, and JSON Diff can compare lifecycle settings. Neither accesses storage or aborts uploads. Execute approved cleanup only through the actual provider tools and verified targets.
Conclusion
Treat incomplete multipart uploads as distinct workflow state. Inventory them, identify active work, choose an age policy consistent with the product, and verify the cleanup outcome. Reliable completion and cancellation handling reduce the abandoned state that housekeeping must later resolve.