Cloudflare R2: S3 Compatible Storage Setup (2025 Guide)
Find your Cloudflare R2 S3 endpoint fast, create API keys, and connect with AWS CLI, JavaScript SDK (v3), s5cmd, rclone, and BucketMate.
Want to plug Cloudflare R2 into your S3 tooling-AWS CLI, @aws-sdk/client-s3, s5cmd, rclone-or BucketMate? This guide shows the exact R2 S3 endpoint, the env vars to set, and copy-ready examples. Then we’ll connect R2 to BucketMate for a fast, Finder-like UI on macOS.
1) Grab your R2 connection credentials
You need 3 things:
- Endpoint URL (e.g.
https://<account-id>.r2.cloudflarestorage.com) - Access Key ID
- Secret Access Key
Where to find them?
- In the Cloudflare dashboard, go to R2.
- On the overview, copy your Account ID. Then the S3 API endpoint URL is
https://<account-id>.r2.cloudflarestorage.com. - Click Manage R2 API Tokens → Create API Token and copy the Access Key ID and Secret (you’ll only see the secret once).
Heads-up: R2 supports virtual-hosted style (
my-bucket.<account-id>.r2.cloudflarestorage.com) and path-style (<account-id>.r2.cloudflarestorage.com/my-bucket). Use either; if a client misbehaves, force path-style in its settings.
2) AWS CLI: quick setup
Use a fresh terminal session:
export AWS_ACCESS_KEY_ID="<your-access-key-id>"
export AWS_SECRET_ACCESS_KEY="<your-secret-access-key>"
export AWS_REGION="auto"
# Newer AWS CLI also supports service-specific env vars:
export AWS_ENDPOINT_URL_S3="https://<account-id>.r2.cloudflarestorage.com"
List buckets and copy an object:
aws s3 ls --endpoint-url "https://<account-id>.r2.cloudflarestorage.com"
aws s3 cp ./logo.png s3://my-r2-bucket/assets/logo.png \
--endpoint-url "https://<account-id>.r2.cloudflarestorage.com"
Prefer profiles? You can keep using --endpoint-url ... with --profile r2, or set AWS_ENDPOINT_URL_S3 in your shell profile so the CLI picks it up automatically.
3) JavaScript (AWS SDK v3)
Minimal upload using @aws-sdk/client-s3:
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
const s3 = new S3Client({
region: "auto",
endpoint: "https://<account-id>.r2.cloudflarestorage.com",
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
// If a client or library assumes AWS-only virtual hosting, un-comment:
// forcePathStyle: true,
});
await s3.send(new PutObjectCommand({
Bucket: "my-r2-bucket",
Key: "welcome.txt",
Body: "Hello from Cloudflare R2!",
ContentType: "text/plain",
}));
Key settings
region: "auto"is required for R2.- Use the account-scoped endpoint shown above.
- Toggle
forcePathStyleonly if your stack insists on virtual-hosted bucket subdomains.
4) s5cmd & rclone (fast transfers)
s5cmd
# Install: macOS → brew install peak/tap/s5cmd
AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... AWS_REGION=auto \
s5cmd --endpoint-url https://<account-id>.r2.cloudflarestorage.com \
cp ./big.iso s3://my-r2-bucket/
rclone (preset provider)
# Guided setup
rclone config
# Choose: "Amazon S3 Compliant Storage Providers" → "Cloudflare R2 storage"
# Enter access key, secret, region=auto, endpoint=https://<account-id>.r2.cloudflarestorage.com
# Then:
rclone ls r2:my-r2-bucket
rclone copy ./folder r2:my-r2-bucket/folder
5) Use R2 inside BucketMate
BucketMate is a native macOS app for managing S3-compatible storage with a familiar, Finder-like interface.
- Open BucketMate → Add connection → Cloudflare R2.
- Input your Endpoint URL, Access Key ID, Secret.
- Click Test Connection to verify your credentials.
- Once verified, click Connect to browse your buckets just like in Finder.
Troubleshooting
- AccessDenied: Re-create the API token with Edit or appropriate permissions for your buckets.
- 403/HeadBucket issues: Set path-style addressing in your client (e.g.,
forcePathStyle: truein SDKs). - NoSuchBucket: Bucket name must follow S3 rules (lowercase, numbers, hyphens); verify the spelling.
- Signature mismatch: Ensure your machine clock is correct; SigV4 is time-sensitive.
- HTTP rejected: Use
https://for all endpoints.