Cloudflare R2
Cloudflare R2 is an S3-compatible object storage service with zero egress fees. It is included in all Cloudflare accounts and integrates with Cloudflare’s global network for CDN delivery. WP Media Cloud connects to R2 using S3-compatible credentials and supports SigV4 signed URLs for WooCommerce secure downloads.
Before you start#
You will need:
- A Cloudflare account with R2 enabled. R2 requires a payment method on file even to use the free tier.
- An R2 bucket.
- An R2 API token with read and write permissions on the bucket.
- Your Cloudflare Account ID.
- Optionally, a custom domain connected to your R2 bucket for public access.
Step 1: Create an R2 bucket#
Log in to the Cloudflare dashboard and go to R2 Object Storage. Click Create Bucket. Give the bucket a name — bucket names must be lowercase and can contain letters, numbers, and hyphens. Select a storage location if you have a preference, or leave it on automatic. Click Create Bucket.
Step 2: Enable public access#
By default, R2 buckets are private. For WP Media Cloud to serve files publicly, you need to either connect a custom domain or enable the R2.dev subdomain.
In your bucket settings, go to the Settings tab and find the Public Access section:
- R2.dev subdomain — Cloudflare provides a free
[bucket-name].[hash].r2.devsubdomain. Enable this for quick setup. Note that Cloudflare rate-limits this subdomain and it is not recommended for high-traffic production sites. - Custom domain — connect a domain you control (it must be on Cloudflare) to serve files without rate limits. This is the recommended option for production. Go to Settings > Custom Domains, click Connect Domain, and follow the prompts.
Step 3: Create an R2 API token#
Go to R2 Object Storage in the Cloudflare dashboard and click Manage R2 API Tokens in the top right. Click Create API Token.
Configure the token as follows:
- Permissions — select Object Read and Write
- Specify bucket — restrict the token to the specific bucket you created
- TTL — leave as indefinite unless you have a rotation policy
Click Create API Token. On the next screen, copy and save all three values before closing the page — they are only shown once:
- Access Key ID
- Secret Access Key
- Endpoint URL — in the format
https://[account-id].r2.cloudflarestorage.com
Step 4: Find your Account ID#
Your Cloudflare Account ID is shown in the right sidebar of the Cloudflare dashboard when you are on the account overview page (before selecting a specific domain). It is a 32-character hexadecimal string. You can also find it in the URL of any Cloudflare dashboard page: https://dash.cloudflare.com/[account-id]/.
Step 5: Connect Cloudflare R2 in WP Media Cloud#
You have two options for connecting R2 to WP Media Cloud. Use whichever suits your setup.
Option A: Setup wizard
Go to WP Media Cloud > Setup Wizard. The wizard walks you through provider selection, credential entry, and CDN configuration. It can list your existing R2 buckets automatically to make bucket selection easier. This is the recommended option for most users.
Option B: wp-config.php constants
Add the following constants above the /* That's all, stop editing! */ line in wp-config.php:
define( 'WPMC_PROVIDER', 'r2' );
define( 'WPMC_R2_ACCOUNT_ID', 'your-account-id' );
define( 'WPMC_R2_ACCESS_KEY_ID', 'your-access-key-id' );
define( 'WPMC_R2_SECRET_ACCESS_KEY', 'your-secret-access-key' );
define( 'WPMC_R2_BUCKET', 'your-bucket-name' );
define( 'WPMC_R2_CDN_URL', 'https://your-r2-cdn-url.com' );
Once the constants are in place, go to WP Media Cloud > Settings > Storage and confirm the plugin has loaded them. Constants defined in wp-config.php override any values saved in the settings panel and are recommended for production sites and version-controlled codebases where credentials should not be editable through the WordPress admin.
The WPMC_R2_CDN_URL value should be your custom domain or R2.dev subdomain URL — not the internal R2 endpoint URL.
Step 6: Test the connection#
Click Test Connection. WP Media Cloud will upload a small test file to your R2 bucket and confirm it can be read back. A green success message confirms the connection is working.
Step 7: Configure CDN delivery (optional)#
If you connected a custom domain to your R2 bucket in step 2, files are already served through Cloudflare’s network. Go to WP Media Cloud > Settings > CDN, select Cloudflare CDN, and enter your custom domain. This ensures all media URLs use your domain rather than the R2.dev subdomain.
For advanced caching rules on your R2 domain, configure Cache Rules in the Cloudflare dashboard under your domain’s Caching settings.
Step 8: Enable WooCommerce secure downloads (optional)#
R2 supports signed URLs natively via SigV4 signing using your existing API credentials. No additional configuration is required in Cloudflare. See WooCommerce Secure Downloads for setup instructions.
Troubleshooting#
Connection test returns 403 Forbidden
The API token does not have the correct permissions. Confirm the token has Object Read and Write permissions on the correct bucket. If you scoped the token to a specific bucket, confirm the bucket name matches exactly.
Connection test returns 404 Not Found
The bucket name is incorrect or the endpoint URL does not match your Account ID. The endpoint URL format must be https://[account-id].r2.cloudflarestorage.com with your actual Account ID.
Files upload successfully but return 403 or Access Denied when accessed
Public access is not enabled on the bucket. Either enable the R2.dev subdomain or connect a custom domain in the bucket’s Settings tab.
R2.dev subdomain returns 429 Too Many Requests
Cloudflare rate-limits the R2.dev subdomain. Connect a custom domain for production use.
CORS errors in the browser console
R2 buckets do not have CORS configured by default. If your site makes direct browser requests to the bucket, add a CORS policy in the bucket’s Settings tab. For standard WP Media Cloud use where files are served by URL rather than fetched via JavaScript, CORS is not required.