Safeguard
Security Guides•

S3 versioning and delete markers: how to recover a deleted object

What S3 versioning actually keeps, why a delete leaves a marker, how lifecycle rules can quietly erase your safety net, and what it costs to keep versions.

Safeguard Security Team
3 min read

With S3 versioning on, deleting an object adds a delete marker instead of removing data, and overwriting adds a new version. You recover by removing the marker or restoring an older version. It only helps if versioning was enabled before the mistake, and lifecycle rules can still expire old versions.

What versioning keeps

The AWS documentation describes versioning as keeping multiple variants of an object in one bucket, so you can preserve, retrieve and restore every version. Overwrites create a new version. Deletes insert a delete marker that becomes the current version, while the earlier data stays.

By default versioning is disabled and you must turn it on. Once enabled, a bucket can never go back to unversioned. You can only suspend it.

The three bucket states

  • Unversioned: the default, deletes are permanent.
  • Versioning enabled: every write gets a version ID.
  • Versioning suspended: new writes stop creating versions, and existing versions stay.

Objects that existed before you enabled versioning get a version ID of null. Enabling versioning does not change them, only how future requests treat them.

Recovering from a delete

  1. List the versions of the key, not just the current object.
  2. Find the delete marker at the top.
  3. Remove the delete marker by deleting it by its version ID. The previous version becomes current again.
  4. Check the object content before telling anyone it is fixed.

If the damage was an overwrite instead, copy the older version over the current one, which creates yet another version and keeps the history clean.

Cost and lifecycle: the quiet trap

AWS states that each version is a full object, not a diff, so three versions are billed as three objects. Teams respond by adding lifecycle rules to expire old versions. That is reasonable, and it is also how people erase their recovery window.

The documentation notes a specific case: if you had an expiration rule on an unversioned bucket and want the same permanent delete behaviour after turning on versioning, you need a noncurrent expiration configuration. Review those rules and pick a retention that matches how quickly you notice mistakes. If it takes your team two weeks to notice a bad batch job, a three day window is not protection.

What versioning does not do

It does not stop someone with delete permissions from deleting specific versions permanently. For that you need extra protection such as MFA delete or Object Lock, covered in our Object Lock post.

It also does not cover the rest of your system. Database rows, configuration and secrets live elsewhere. See what to back up besides the database.

Safeguard can record whether storage controls like versioning are enabled as part of compliance evidence, and the free scan at gold.safeguard.sh/scan covers your dependencies.

Quick check

Can I enable versioning after the damage?

It will not bring back what was already deleted from an unversioned bucket. Turn it on now so the next mistake is recoverable.

Does a delete marker use storage?

It is a small marker, but the earlier versions it hides are stored and billed in full.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.