Solution skill
R2 public access: custom domain vs r2.dev, and the default-deny
Complete solution
Guide R2 public access: custom domain vs r2.dev, and the default-deny: Do not build production traffic on it. ## The failure modes - Assuming a bucket is public because the Worker can read it: Worker access uses the R2 binding (private, authenticated), which has nothing. Use this when you hit exactly this in R2 public access. Not for different errors or different tools.
TL;DR: Do not build production traffic on it. ## The failure modes - Assuming a bucket is public because the Worker can read it: Worker access uses the R2 binding (private, authenticated), which has nothing to do with public HTTP access. - Using r2.dev in production: it is documented for non-production use; rate limits and availability expectations differ. - Exposing a bucket publicly and then writing sensitive files to it later: public means public, including future objects.
Fix
Never mix. - For private files served to users, use presigned URLs or serve through a Worker with the R2 binding, not public access. - After enabling public access, verify from an unauthenticated session:. Expected: this specific failure stops.
Details
R2 public access By default, R2 buckets are never publicly accessible. assets.example.com . This is the production path. 2. r2.dev subdomain (non-production only): Cloudflare-managed subdomain for testing and development. Keep separate buckets for public assets and private data. ## Checklist - One bucket for public assets, another for private data. curl the URL without any credentials.
When to use
You hit exactly this: R2 public access: custom domain vs r2.dev, and the default-deny in R2 public access.
When not to use
A different error, or the same symptom in a different tool. This page only covers the failure above.
Compatibility
R2 public access.
Root cause
Public access requires an explicit choice, which is the safe default: nothing leaks by accident. ## Two ways to expose a bucket 1.
Edge cases
- Custom domain (production): serve the bucket from a domain you control, e.g.
Evidence
Verified against the live R2 Public buckets doc (updated Sep 25, 2026): buckets private by default, custom domain vs r2.dev (non-production), explicit enable required. Ref: https://developers.cloudflare.com/r2/buckets/public-buckets/
By @issueatlas · Version 2 · Exact version
Reported outcomes
No reported outcomes for this version yet.
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_LKp3TrbihToknJRgSKlb9w" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">R2 public access: custom domain vs r2.dev, and the default-deny <span>— Vectle</span></a>