Skip to main content
CoreWeave AI Object Storage only deletes a bucket once it is completely empty. The bucket must contain no current objects, no noncurrent object versions, no delete markers, and no incomplete multipart uploads. If any of these remain, s3:DeleteBucket returns BucketNotEmpty. This guide walks through emptying a bucket of every kind of content it can hold, then deleting the empty bucket. The four cleanup steps are independent and can run in parallel: skip any that do not apply to your bucket.

Prerequisites

Before you start:
Deleting a bucket is permanent. Once a bucket and its contents are deleted, the data cannot be recovered. Confirm the bucket name and contents before you start.

Step 1: Delete current objects

Delete all current-version objects in the bucket.
aws s3 rm with --recursive removes every current object in the bucket. Replace [BUCKET-NAME] with the name of your bucket.
Delete all current objects with AWS CLI
aws s3 rm s3://[BUCKET-NAME] --recursive
For very large buckets, see Bulk deletion performance for tuning options.

Bulk deletion performance

For large buckets, choose the deletion approach that matches the scale you need:
  • s3:DeleteObjects batches delete up to 1000 objects per call. The Boto3 example above uses this approach. It is the most efficient way to delete millions of objects from a single client.
  • Parallel aws s3 rm workers: Split deletion across prefixes and run multiple aws s3 rm s3://[BUCKET-NAME]/[PREFIX] --recursive commands in parallel. Reasonable for hundreds of thousands of objects when the keys partition cleanly by prefix.
  • rclone delete: Run rclone delete [REMOTE]:[BUCKET-NAME] for incremental deletion with progress reporting. Combine with --transfers to control concurrency. See Versioned buckets for rclone configuration.
Mass deletion is a write-heavy workload. Running thousands of concurrent delete operations against a single bucket can affect other clients reading from or writing to the same bucket. For very large deletions, schedule the work outside peak hours, or stage it across prefixes.
If you do not need immediate deletion, an Expiration lifecycle rule deletes objects on a schedule without consuming client capacity.

Step 2: Delete noncurrent versions and delete markers

Skip this step if the bucket does not have versioning enabled or suspended. To check:
Check the versioning status of a bucket
aws s3api get-bucket-versioning --bucket [BUCKET-NAME]
If the response includes "Status": "Enabled" or "Status": "Suspended", the bucket can hold noncurrent versions and delete markers, both of which must be removed before deletion. The simplest way to remove every noncurrent version and delete marker is to list them and delete them by VersionId.
This shell loop pages through list-object-versions and deletes every version and delete marker it finds. Replace [BUCKET-NAME] with the name of your bucket.
Delete all versions and delete markers with AWS CLI
BUCKET="[BUCKET-NAME]"

aws s3api list-object-versions --bucket "$BUCKET" \
    --query '{Objects: Versions[].{Key: Key, VersionId: VersionId}}' \
    --output json > versions.json

aws s3api delete-objects --bucket "$BUCKET" --delete file://versions.json

aws s3api list-object-versions --bucket "$BUCKET" \
    --query '{Objects: DeleteMarkers[].{Key: Key, VersionId: VersionId}}' \
    --output json > markers.json

aws s3api delete-objects --bucket "$BUCKET" --delete file://markers.json
If the bucket has more than 1000 versions or delete markers, repeat both blocks until both listings return no entries.
For more on versioned bucket workflows, see Versioned buckets.

Step 3: Abort incomplete multipart uploads

Incomplete multipart uploads do not appear in normal object listings, but they consume storage and prevent bucket deletion. They are the single most common reason DeleteBucket returns BucketNotEmpty when the bucket appears empty in the Cloud Console or in aws s3 ls. To check whether the bucket has incomplete multipart uploads:
List incomplete multipart uploads
aws s3api list-multipart-uploads --bucket [BUCKET-NAME]
If the response is empty, skip to Step 4. If it lists any uploads, follow Abort incomplete multipart uploads to remove them, then continue.

Step 4: Delete the empty bucket

Once the bucket has no current objects, no noncurrent versions, no delete markers, and no incomplete multipart uploads, delete it.
Replace [BUCKET-NAME] with the name of your bucket.
Delete the empty bucket with AWS CLI
aws s3api delete-bucket --bucket [BUCKET-NAME]
A successful deletion returns no output. If you still get BucketNotEmpty, re-run the listings from each step above to find what remains.

Prevent BucketNotEmpty errors

To keep buckets ready for deletion at any time, apply a bucket lifecycle policy that includes:
  • An AbortIncompleteMultipartUpload rule. This is the most common cause of bucket-delete failures and the only way to keep abandoned uploads from accumulating without active intervention.
  • A NoncurrentVersionExpiration rule on versioned buckets. Without it, every overwrite leaves a noncurrent version that must be cleaned up before deletion.
Last modified on June 8, 2026