Operations8 min readSeptember 23, 2026

How to recover deleted or overwritten files in Amazon S3

How S3 Versioning changes a delete or overwrite into a recoverable event, with safe console and CLI steps, lifecycle controls, and the limits to know before an incident.

JeVaughn Ferguson
Founder, developer
The short version

Check whether Versioning was active when the change happened. Remove the current delete marker to reveal a deleted file, or copy a known older version onto the same key to reverse an overwrite while preserving history. Then bound the recovery window with a reviewed noncurrent-version lifecycle rule.

A file disappears from a shared prefix, or yesterday's spreadsheet is replaced by the wrong copy. The first question is not which recovery command to run. It is whether S3 Versioning was enabled on the bucket when the change happened.

When Versioning is enabled, an ordinary delete usually adds a delete marker and an overwrite creates a new current version. The older bytes remain available by version ID. This guide shows how to tell those cases apart, recover without throwing away more history, and put a limit on the storage that old versions consume.

Start by checking the bucket and the object history

Open the bucket's Properties tab in the S3 console and check Bucket Versioning. If it says Enabled, switch on Show versions in the Objects view and search for the exact key. A deleted object should appear with one or more delete markers alongside its data versions. An overwritten object should show several data versions with different version IDs and modified times.

Versioning protects only writes and deletes that happen after it is enabled. If the bucket was unversioned when the only copy was deleted or replaced, turning Versioning on now cannot reconstruct it. Check any replica bucket, backup, application export or other copy before concluding that the file is gone.

A Suspended bucket needs extra care. Versions created while Versioning was enabled still keep their IDs, but new writes use a null version ID. Record what the console shows before changing anything, especially if the key has both numbered and null versions.

aws s3api get-bucket-versioning --bucket amzn-s3-demo-bucket

aws s3api list-object-versions \
  --bucket amzn-s3-demo-bucket \
  --prefix 'finance/forecast.xlsx'

Recover a file hidden by a delete marker

In a versioned bucket, a simple DeleteObject request does not normally erase the existing data version. S3 creates a delete marker and makes that marker current, so an ordinary GetObject request behaves as though the key is missing.

In the console, turn on Show versions, select the current delete marker for the exact key, choose Delete, and confirm permanent deletion of that marker. The most recent data version below it becomes current again. Do not select a data version unless you intend to remove that version permanently.

The CLI operation must include the delete marker's version ID. Running delete-object without --version-id creates another delete marker instead of revealing the file. Copy the ID from list-object-versions and check the key again after the command completes.

aws s3api delete-object \
  --bucket amzn-s3-demo-bucket \
  --key 'finance/forecast.xlsx' \
  --version-id 'delete-marker-version-id'

Roll back an overwrite without deleting later history

An overwrite is different: the wrong upload is a real current data version, with the earlier version still underneath it. You can make the older content current by permanently deleting every newer version, but that removes useful evidence and makes a second mistake harder to undo.

AWS recommends copying the chosen older version back onto the same key. CopyObject reads the source by version ID and writes a new current version. The mistaken upload, the recovered copy and the earlier original all remain in the history. Confirm the older version by modified time, size and, where available, checksum before copying it.

The role doing the recovery needs permission to read the chosen version and write the destination key. A KMS-encrypted object can also require permission to use its KMS key. Test the command on one key and record the source version ID in the incident or change record.

aws s3api copy-object \
  --bucket amzn-s3-demo-bucket \
  --key 'finance/forecast.xlsx' \
  --copy-source 'amzn-s3-demo-bucket/finance/forecast.xlsx?versionId=older-version-id'

Know which actions are permanent

Deleting a specific data version by version ID permanently removes that version. S3 Versioning does not provide another recovery layer beneath it. The same is true when a lifecycle rule expires a noncurrent version. Treat both operations as disposal, with narrower permissions and a longer review path than an ordinary delete.

S3 Object Lock is the AWS control for versions that must resist permanent deletion for a retention period or legal hold. It requires Versioning and protects individual object versions. It does not stop someone from uploading a new version or placing a delete marker above a protected version, so recovery procedures still need to include Show versions and version IDs.

Keep enough history without keeping every version forever

Each stored version is a complete object and is billed as one. Replacing a 2 GB presentation ten times can leave roughly 20 GB of stored versions, even though normal listing shows one current key. Versioning needs a recovery window and a matching lifecycle rule, not a vague promise to clean up later.

Use NoncurrentVersionExpiration to remove noncurrent versions after the recovery period your business has chosen. A rule can also retain a number of newer noncurrent versions, but AWS requires a noncurrent-days setting when that option is used. Review Object Lock retention before applying expiration, because a protected version remains protected until its retention or legal hold permits deletion.

  • Choose the recovery window from the time it usually takes your team to notice a bad delete or overwrite.
  • Estimate storage from the size and replacement rate of the files, not only the size of the current objects.
  • Test the lifecycle rule on a narrow prefix before applying it to the whole bucket.
  • Monitor noncurrent version storage separately so a busy prefix does not become a surprise bill.

Separate everyday file access from recovery administration

Most people need the current file, not permission to permanently delete versions. Keep recovery and lifecycle administration with a small AWS operations group, use CloudTrail data events where object-level history is required, and give the wider team an interface that works with current objects through named roles.

BucketDesk browses and previews the current files in a bucket through a scoped IAM role. Its Business storage tools cover uploads, confirmed deletes and manual restores from Glacier storage classes; recovery of prior S3 versions remains an AWS console or CLI task. You can try the file workspace with simulated data before connecting a bucket.

Try it in BucketDesk

Starter is free. Deploy a scoped role with CloudFormation, sign in, and browse, without handing anyone an access key.

Connect a bucket

Primary sources

Discussion

0 comments · open to guests · moderated
Comments appear after a quick review.

Liked this? Get the next article by email. No schedule, no filler, one click to leave.

Keep reading

All writing →