Skip to content

[R2] R2-5726: Document 409 status and precedence for ObjectLockedByBucketPolicy - #34582

Open
helloimalastair wants to merge 2 commits into
productionfrom
document-409-objectlockedbybucketpolicy
Open

helloimalastair wants to merge 2 commits into
productionfrom
document-409-objectlockedbybucketpolicy

Conversation

@helloimalastair

Copy link
Copy Markdown
Collaborator

Summary

R2 returns 409 Conflict for ObjectLockedByBucketPolicy (10069), but the error codes page listed it as 403. When a write is blocked by a bucket lock rule and would also fail a conditional header such as If-None-Match: *, the lock check is evaluated first, so the response is 409 ObjectLockedByBucketPolicy rather than 412 PreconditionFailed. This change brings docs into alignment with existing behaviour.

Documentation checklist

@helloimalastair
helloimalastair requested review from a team, rdimaio and vy-ton as code owners October 23, 2026 23:05
@github-actions github-actions Bot added the product:r2 R2 object storage: https://developers.cloudflare.com/r2 label Oct 23, 2026
@cloudflare-docs-bot

cloudflare-docs-bot Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

AI Review

✅ Reviewed 10b4d66 · 0 findings · incremental

Commands
  • /review Run a review now.
  • /full-review Review the entire PR diff.
  • /disable-auto-review Stop automatic reviews.
  • /rebase Rebase against production.

@cloudflare-docs-bot

Copy link
Copy Markdown
Contributor

Review coverage

🟡 1 ownership area needs approval.

Suggested reviewers: @vy-ton @WalshyDev

Needs approval Eligible approvers Suggested
r2 @carolx715, @enorman-cf, @helloimalastair, @rdimaio, @soumyakhanna05, @vy-ton, @cloudflare/product-owners vy-ton, WalshyDev
CODEOWNERS mappings for displayed areas (1)
Pattern Owners
/src/content/docs/r2/ @carolx715, @enorman-cf, @helloimalastair, @rdimaio, @soumyakhanna05, @vy-ton, @cloudflare/product-owners

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://document-409-objectlockedbybucketpolicy.previews.developers.cloudflare.com (commit 10b4d66)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://692bccc0.previews.developers.cloudflare.com 10b4d66 2026-10-26T18:13:31.992Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://a2b77c82.previews.developers.cloudflare.com 9ab873f 2026-10-23T23:11:53.976Z Visit the dashboard ↗

Comment thread src/content/docs/r2/buckets/bucket-locks.mdx Outdated
Comment thread src/content/docs/r2/api/error-codes.mdx Outdated
@helloimalastair
helloimalastair force-pushed the document-409-objectlockedbybucketpolicy branch from 2ce1f53 to 10b4d66 Compare October 26, 2026 18:05
| 100100 | EntityTooLarge | 400 | Object exceeds maximum size (5 GiB for single upload, 5 TiB for multipart). | Use [multipart upload](/r2/objects/upload-objects/#multipart-upload) for objects larger than 5 GiB. Maximum object size is 5 TiB. |
| 10012 | MetadataTooLarge | 400 | Custom metadata exceeds the 8,192 byte limit. | Reduce custom metadata size. Maximum is 8,192 bytes total for all custom metadata. |
| 10069 | ObjectLockedByBucketPolicy | 403 | Object is protected by a bucket lock rule and cannot be modified or deleted. | Wait for the retention period to expire. Refer to [bucket locks](/r2/buckets/bucket-locks/). |
| 10069 | ObjectLockedByBucketPolicy | 409 | Object is protected by a bucket lock rule and cannot be modified or deleted. If a conditional header on the object being written would also fail, this error is returned instead of `PreconditionFailed`. `CopyObject` source conditions (`x-amz-copy-source-if-*`) are evaluated before the destination lock check, so those return `412` even when the destination is locked. | Wait for the retention period to expire. Refer to [bucket locks](/r2/buckets/bucket-locks/). |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[IMPORTANT] Copying an object onto itself returns 409 on a locked object, not the 412 this row promises

Problem: The new CopyObject sentence says source conditions always win over the destination lock check. That holds only for copies to a different key, storage-class changes, and SSE-C copies. For a same-key copy (the usual in-place metadata update), the lock check runs first.

Evidence: In src/content/docs/r2/api/error-codes.mdx:66, `CopyObject` source conditions (`x-amz-copy-source-if-*`) are evaluated before the destination lock check, so those return `412` even when the destination is locked. In r2-gateway-worker/src/durable_objects/bucket/server.ts:13838-13861, the lock check returns ObjectLockedByBucketLockRule before sourceCopyConditions is evaluated. In r2-metadata-worker/src/store/bucket.ts:919, WHEN object_locked THEN 'OBJECT_LOCKED_BY_BUCKET_LOCK_RULE' precedes every IF_*_FAILED branch. A same-key CopyObject with x-amz-metadata-directive: REPLACE and a failing x-amz-copy-source-if-match therefore returns 409.

Suggested fix: Narrow the sentence to the cases where it is true and name the exception, or drop it. For example: "For a copy to a different key (or one that changes storage class or uses SSE-C), CopyObject source conditions are evaluated before the destination lock check and return 412. For a copy of an object onto itself, the lock check runs first and returns 409."

SCR v2.0.1 run by rdimaio on 10b4d66

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

product:r2 R2 object storage: https://developers.cloudflare.com/r2 size/xs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants