Repository navigation
[R2] R2-5726: Document 409 status and precedence for ObjectLockedByBucketPolicy - #34582
helloimalastair wants to merge 2 commits into
Conversation
AI Review✅ Reviewed Commands
|
Review coverage🟡 1 ownership area needs approval. Suggested reviewers: @vy-ton @WalshyDev
CODEOWNERS mappings for displayed areas (1)
|
🚀 Deploying Preview to Cloudflare 🚀Preview URL: https://document-409-objectlockedbybucketpolicy.previews.developers.cloudflare.com (commit 10b4d66)This URL reflects your latest Preview deploymentPreview Deployments by commit
|
2ce1f53 to
10b4d66
Compare
| | 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/). | |
There was a problem hiding this comment.
[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
Summary
R2 returns
409 ConflictforObjectLockedByBucketPolicy(10069), but the error codes page listed it as403. When a write is blocked by a bucket lock rule and would also fail a conditional header such asIf-None-Match: *, the lock check is evaluated first, so the response is409 ObjectLockedByBucketPolicyrather than412 PreconditionFailed. This change brings docs into alignment with existing behaviour.Documentation checklist