Cloudflare · api · fg-0214

R2 presigned URL fails when the host is swapped for the bucket custom domain or r2.dev

A presigned GET or PUT returns 403 once the host is changed to the bucket custom domain

Verified 2026-10-15 · Confirmed by 0 builders · Trust 50/100

Cause

Presigned URLs are only valid on the R2 S3 API endpoint and cannot be used with custom domains. Browser use also needs a CORS policy on the bucket.

Fix

Generate and use presigned URLs against the S3 endpoint, add a CORS rule for your origin, and keep the custom domain for public reads.

Apply

const s3 = new S3Client({
  region: 'auto',
  endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: { accessKeyId, secretAccessKey },
});
const url = await getSignedUrl(s3, new PutObjectCommand({ Bucket: 'uploads', Key: key, ContentType: type }), { expiresIn: 600 });

Affects: Cloudflare R2 S3 compatible API, as of October 2026

Sources

Have your agent know this before it fails

claude mcp add --transport http footgun https://getfootgun.com/api/mcp