If your S3 bucket has versioning enabled, a simple delete can hide the current object without removing the stored versions that still incur storage charges.
Short answer: In a versioning-enabled bucket, a delete request that does not name a version ID does not erase the object. AWS says that "Because the object is in a versioning-enabled bucket, the object is not deleted," and that S3 instead adds a delete marker that "becomes the current version of the object." A 404 or a listing that omits the key tells you what is current, not what is stored. And AWS states that "Normal Amazon S3 rates apply for every version of an object that is stored and transferred, including noncurrent object versions."
Scope: This guide covers general purpose S3 buckets with versioning enabled. Buckets with versioning suspended, directory buckets, Object Lock, MFA delete and other AWS charges are outside it, and we make no claim about them. We read two public AWS documentation pages on October 7, 2026 (23:36 KST). We did not sign in to an AWS account, list or change a bucket, or look at anyone’s bill. This is not a cost estimate and not a deletion tutorial.
Why a missing object can still have stored versions
AWS defines a simple DELETE as "a request that doesn’t specify a version ID." On a versioning-enabled bucket, its page on deleting object versions says such a request "cannot permanently delete an object." What happens instead: "Amazon S3 inserts a delete marker in the bucket, and that marker becomes the current version of the object with a new ID."
From the outside, that looks like a deletion. When the current version is a delete marker, a GET without a version ID returns "A 404 (Not Found) error," and AWS adds that "a ListObjectsV2 or ListObjects request doesn’t return objects whose current version is a delete marker." So the object is gone from the normal view, while the earlier versions sit behind the marker. AWS’s own wording: S3 "behaves as though the object has been deleted (even though it has not been erased)."
The two checks most people run first, opening the object and listing the bucket, both look only at the current version. Neither is an inventory of what is stored.
Visible, retained, billed: four different checks
| What you see | What may remain | What this proves |
|---|---|---|
| The key is missing from the current object list, or a GET returns 404 | A current delete marker with earlier versions behind it | Not evidence that all versions were removed. AWS: "The only way to list delete markers (and other versions of an object) is by using a ListObjectVersions request." |
| A noncurrent version is present | Its object data | Stored versions are billed. "Normal Amazon S3 rates apply for every version of an object that is stored and transferred, including noncurrent object versions." |
| A delete marker is present | A key name and version ID, no object data | A small charge, not a free one. "Delete markers accrue a minimal charge for storage in Amazon S3." |
| A Lifecycle Expiration rule is in place | Current and noncurrent versions are handled by different actions | No automatic promise that history was removed. Current-version Expiration keeps the current version as a noncurrent version and adds a delete marker; removing noncurrent versions is a separate action. |
On the third row, AWS gives the size rule: "The storage size of a delete marker is equal to the size of the key name of the delete marker." The UTF-8 encoding of the key name adds one to four bytes per character, and "Delete markers are stored in the S3 Standard storage class." We do not convert that into a dollar figure; AWS’s versions page refers you to its Amazon S3 pricing page for rates.
A read-only cost inventory before changing retention
Before anyone touches versioning, Lifecycle rules or individual versions, write down what exists. Use only the tools and permissions you already have, and record rather than change. Leave a cell UNKNOWN until the account owner has confirmed it.
| Field | Your value | Why it matters |
|---|---|---|
| Observation date/time and bucket scope (keep account IDs and bucket names private) | UNKNOWN | Version counts and charges change over time; a dated record keeps the inventory honest. |
| Current versioning state | UNKNOWN | If versioning is not enabled, stop: this article’s mechanism does not apply as written. AWS notes that delete markers are also created in suspended buckets; that case is not covered here, so do not read "not enabled" as "no hidden versions". |
| Versions, noncurrent versions and delete markers you can see | UNKNOWN | AWS lists these only through ListObjectVersions, shown in the console as Show versions. For counts across buckets, AWS points to S3 Storage Lens metrics. |
| Storage class and billing category | UNKNOWN | Delete markers sit in S3 Standard; record each version’s class as your own listing shows it. Do not guess currency or unit rates. |
| Retention owner and recovery or compliance needs | UNKNOWN | Old versions may be the only copy someone is relying on. |
| Official pages checked and open questions for the owner | UNKNOWN | Separates what AWS documents from what only your account can answer. |
AWS’s two pages name S3 Storage Lens as a way "to see how many current and noncurrent object versions that your buckets have" and to "find out how many delete markers you have and what storage class they’re stored in." We did not set up Storage Lens and do not cover its configuration or cost here.
Why current-version expiration is not the same as expiring old versions
AWS describes two separate Lifecycle actions for versioning-enabled buckets:
- Expiration "applies to the current object version." For a versioned bucket, "Instead of deleting the current object version, Amazon S3 retains the current version as a noncurrent version by adding a delete marker, which then becomes the current version." The data stays; it simply stops being current.
- NoncurrentVersionExpiration "applies to noncurrent object versions, and Amazon S3 permanently removes these object versions. You cannot recover permanently removed objects."
So a rule that only expires current versions adds delete markers, and, unless a separate NoncurrentVersionExpiration action exists, the stored history keeps accruing charges. The action that does remove history is permanent. That is exactly why this guide stops at the inventory: whether to remove noncurrent versions, and after how long, is a decision for the bucket’s owner with its recovery and compliance needs in hand, not a setting we recommend.
FAQ
Does a 404 prove all stored versions are gone? No. A GET without a version ID returns a 404 when the current version is a delete marker, while earlier versions can remain stored.
Are delete markers free? No. AWS says they "accrue a minimal charge for storage," sized by the key name and stored in S3 Standard.
Does current-version expiration erase earlier versions? No. In a versioning-enabled bucket, Expiration keeps the current version as a noncurrent version and adds a delete marker. Removing noncurrent versions is a separate action, NoncurrentVersionExpiration, and it is permanent.
Does this guide calculate my savings? No. Savings are UNKNOWN without your own version inventory and bill. Changing retention does not, by itself, tell you what your next bill will be.
Sources and next check
Read AWS’s Working with delete markers page first, then record your bucket’s current state in the worksheet above before anyone changes retention. The Lifecycle and noncurrent-version billing points come from Deleting object versions from a versioning-enabled bucket. Both were read October 7, 2026 (23:36 KST), and AWS can change them at any time. Nothing here is a test result, an account inspection or a savings estimate, and there are no affiliate links on this page.