An S3 bucket had versioning enabled and later suspended. What does S3 do with new uploads and with the versions already stored, and why can that silently lose data?
answer
- three states, and one of them is a trap
- enabled, suspended — but never back to plain
- a reserved version ID that is a value, not an absence
- one slot per key, so writes clobber
- old versions stay, and stay billed
basics
~20 sSuspending stops S3 from minting new version IDs: every later upload to a key is stored with the literal version ID null and overwrites the previous null version. Versions created while versioning was enabled are kept and still billed.
solid answer
~40 sA bucket has three versioning states: never-versioned, `Enabled`, and `Suspended` — and `PutBucketVersioning` can move it between Enabled and Suspended but can never take it back to never-versioned. While suspended, each `PutObject` stores the object with the literal version ID `null`, and because a key can hold only one null version, the next upload *replaces* it — that is real, unrecoverable data loss, exactly what versioning was supposed to prevent. Everything written while versioning was enabled keeps its version ID, stays retrievable with `GetObject --version-id`, and keeps costing money, so suspending does nothing for the storage bill. A `DELETE` during suspension removes the existing null version and inserts a delete marker with version ID `null`, leaving the older real versions behind it untouched.
code
bash · 10 linesaws s3api put-bucket-versioning --bucket my-bucket \
--versioning-configuration Status=Suspended
# Both uploads land on the same reserved version ID: "null"
aws s3api put-object --bucket my-bucket --key data.csv --body v2.csv
aws s3api put-object --bucket my-bucket --key data.csv --body v3.csv # v2 is gone
# Versions written before suspension still have real IDs and are still there
aws s3api list-object-versions --bucket my-bucket --prefix data.csv \
--query 'Versions[].[VersionId,IsLatest,LastModified]' --output tablego deeper
Recall that S3 versioning can be enabled and suspended but never fully removed, and that suspended buckets store new uploads under the version ID null.
Explain the mechanics: one null slot per key so writes clobber each other, pre-existing versions retained with real IDs, and a version-less delete inserting a null delete marker.
Show operational judgment — recognise suspension as a data-loss risk for overwrite-heavy workloads, know it does not reduce cost, and reach for noncurrent-version expiration instead.
Own the guardrail: decide whether PutBucketVersioning belongs in any application role at all, and whether MFA delete or an organization policy should make suspension a deliberate, audited act rather than an available API call.
## Three states, one-way door S3 versioning is a bucket-level setting with three states: - **Never versioned** — the default for a new bucket. Every object has version ID `null` and an overwrite replaces the bytes. - **Enabled** — every write mints a new unique version ID; deletes insert delete markers. - **Suspended** — versioning is switched off for *future* writes, but the bucket remembers it was versioned. ```bash aws s3api put-bucket-versioning --bucket my-bucket \ --versioning-configuration Status=Suspended aws s3api get-bucket-versioning --bucket my-bucket # { "Status": "Suspended" } ``` The one-way door matters: there is no API call that returns a bucket to the never-versioned state. The best you can do is suspend it and expire the accumulated versions with a lifecycle rule, or copy the data into a fresh bucket. ## What happens to new writes During suspension every `PutObject` stores the object under the reserved version ID `null`. A key can hold at most one null version, so: 1. Upload `data.csv` → stored as version `null`. 2. Upload `data.csv` again → the previous **null version is discarded** and replaced. The second upload destroys the first. That is ordinary unversioned behaviour, which is fine if it is what you intended — and a trap if someone suspended versioning "temporarily to save money" while the application kept overwriting the same keys. Meanwhile any version with a real ID, created before suspension, is safe: it can only be removed by an explicit versioned delete or a lifecycle rule. ## What happens to deletes A `DELETE` with no version ID during suspension does two things in one call: it removes the null version if one exists, and it inserts a **delete marker whose version ID is `null`**. The key then reads as 404 while every pre-suspension version sits behind the marker, still retrievable by ID. Removing that marker exposes the newest real version again, exactly as in an enabled bucket. A `DELETE` that names a version ID behaves the same as ever: that version is destroyed permanently. ## Why the bill does not move Suspending versioning does not delete anything. Every noncurrent version created while versioning was enabled remains stored at full size in its storage class. Teams who suspend versioning in response to a cost alarm are usually disappointed: the growth stops, the existing mass does not shrink. The lever that actually reduces the bill is noncurrent-version expiration in a lifecycle configuration, which works on a suspended bucket just as it does on an enabled one. ## Reading a mixed bucket After suspension a single key can hold a genuinely confusing history: several real versions, one null version, and a null delete marker. `ListObjectVersions` shows all of them, with `IsLatest` marking the current one; a plain `ListObjectsV2` shows only the current version and hides markers entirely. When investigating "where did my file go", always list versions, not objects. ```bash aws s3api list-object-versions --bucket my-bucket --prefix data.csv \ --query 'Versions[].[VersionId,IsLatest,Size]' ``` ## Mixed-state gotchas worth naming - **MFA delete follows the versioning state.** MFA delete is configured on the same `PutBucketVersioning` call, so changing the versioning state of a bucket with MFA delete on requires the root user's MFA token — suspension is not something an ordinary automation role can do quietly. - **Features that require versioning break.** Replication and Object Lock both require versioning `Enabled`. Suspending a bucket that is a replication source stops replication rather than silently degrading it. - **Objects that predate enablement** already carry the `null` version ID, so a bucket can contain null versions that were never the result of suspension. ## The interview point The question is really about whether you understand that S3's version ID `null` is a *value*, not an absence — a single reserved slot that later writes overwrite. Candidates who say "suspending versioning turns the bucket back to normal" have half of it: writes behave normally again, but the bucket keeps its history, keeps its bill, and can never go back to being a plain bucket.
- A team suspends versioning after a cost alarm. Does the bill go down?No. Suspension stops new versions being created but deletes nothing, so every noncurrent version keeps billing at full size. The lever that actually reclaims space is a lifecycle rule with noncurrent-version expiration, plus a rule to remove expired object delete markers. Suspension only flattens the growth curve.
- What does a version-less DELETE do while a bucket is suspended?It removes the key's null version if one exists and inserts a delete marker with version ID `null`, so the key reads as 404. Versions created while versioning was enabled sit behind that marker untouched; removing the marker makes the newest of them current again.
saying these in an interview costs you the question
- Thinks suspension returns the bucket to a never-versioned state
- Believes suspension deletes the existing versions
- Assumes suspended uploads still get unique version IDs
- Says null means the object has no version at all
- Suspends versioning as a cost-reduction measure