Home / AWS

AWSRunbookAdvanced

Sev1: S3 objects deleted or overwritten — recover with versioning, replicas and backups

Recover S3 data after an accidental delete or bad overwrite. Remove delete markers in bulk, restore earlier versions, fall back to replicas or AWS Backup, and stop the next incident with Object Lock and MFA delete.

Deepak Bhardwaj2 min read

Applies toAmazon S3 general purpose buckets, AWS Backup for S3, AWS CLI v2

First: stop the deleter

Disable the job, lifecycle rule or user causing the deletes. Check for a lifecycle rule that expires current versions or noncurrent versions — it may keep deleting while you recover.

aws s3api get-bucket-lifecycle-configuration --bucket prod-invoices

1. Is versioning on?

aws s3api get-bucket-versioning --bucket prod-invoices
Status Recovery path
Enabled Delete markers and previous versions — Steps 2–3
Suspended Versions created before suspension still exist
Empty (never enabled) Only replicas or backups — Step 4

2. Deleted objects: remove delete markers

In a versioned bucket, a delete adds a delete marker. Removing the marker brings the object back.

aws s3api list-object-versions --bucket prod-invoices --prefix 2026/10/ \
  --query "DeleteMarkers[?IsLatest==\`true\`].[Key,VersionId]" --output text > markers.txt
wc -l markers.txt

while read -r key ver; do
  aws s3api delete-object --bucket prod-invoices --key "$key" --version-id "$ver"
done < markers.txt

For millions of objects, generate a manifest (S3 Inventory includes versions and delete markers) and use S3 Batch Operations or a parallel script; a shell loop is too slow.

3. Overwritten objects: restore a previous version

aws s3api list-object-versions --bucket prod-invoices --prefix 2026/10/inv-1001.pdf \
  --query "Versions[].{v:VersionId, latest:IsLatest, modified:LastModified, size:Size}" --output table

aws s3api copy-object --bucket prod-invoices --key 2026/10/inv-1001.pdf \
  --copy-source "prod-invoices/2026/10/inv-1001.pdf?versionId=<good-version-id>"

Copying the old version on top makes it current again and keeps the bad version in history.

Caution

Don't delete the bad versions until you're sure. Deleting a specific version ID is permanent.

4. No versioning: other sources

  • Replication target bucket (CRR/SRR): copy back with aws s3 sync s3://dr-bucket/prefix s3://prod-invoices/prefix. Deletes are not replicated by default, so the replica often still has the data.
  • AWS Backup for S3: start a restore job to the original or a new bucket.
  • Upstream systems: re-run the producer for the affected period.

5. Who did it

CloudTrail data events for S3 must be enabled to see DeleteObject. Server access logs are an alternative.

SELECT eventtime, useridentity.arn, sourceipaddress, count(*) AS deletes
FROM cloudtrail_logs
WHERE eventsource = 's3.amazonaws.com' AND eventname IN ('DeleteObject', 'DeleteObjects')
  AND requestparameters LIKE '%prod-invoices%'
GROUP BY 1, 2, 3 ORDER BY 1 DESC;

Prevent it next time

  • Versioning on every production bucket, with a noncurrent-version expiration rule to control cost.
  • Object Lock (governance or compliance mode) for data that must not be deleted.
  • Replication to another account with a different admin team.
  • Least-privilege policies: no s3:DeleteObject for apps that only write.