DEV Community 👩‍💻👨‍💻

Ehtesham Siddiqui
Ehtesham Siddiqui

Posted on • Originally published at

How To Fix - CORS Error while uploading files on Cloudflare R2 using presigned URLs.

This post was originally posted here at my blog.

Cloudflare R2 Storage allows developers to store large amounts of unstructured data without the costly egress bandwidth fees associated with typical cloud storage services.

While using R2 to upload files with presigned URLs, I started getting the following CORS issue in my browser console:
"Access to fetch at '' from origin http://localhost:3000 has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."

Here is how I solved it using aws-sdk for js V3:

Create an empty node project and install aws-sdk for js v3.

mkdir r2-cors && cd r2-cors
pnpm init
pnpm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
touch cors.js
Enter fullscreen mode Exit fullscreen mode

Add type: "module" into your package.json file.

Next, copy and paste this snippet into cors.js and replace the credentials from your Cloudflare R2 dashboard. Refer here to create the tokens.

import { PutBucketCorsCommand, S3Client } from "@aws-sdk/client-s3";

const s3Client = new S3Client({
  region: "auto",
  endpoint: `https://${CF-ACCOUNT-ID}`, //TODO: replace
  credentials: {
    accessKeyId: `${ACCESS-KEY}`, //TODO: replace
    secretAccessKey: `${ACCESS-SECRET}`, //TODO: replace

async function main() {
  const response = await s3Client.send(
    new PutBucketCorsCommand({
      Bucket: "your-bucket-name", //TODO: replace
      CORSConfiguration: {
        CORSRules: new Array({
          AllowedHeaders: ["content-type"], //this is important, do not use "*"
          AllowedMethods: ["GET", "PUT", "HEAD"],
          AllowedOrigins: ["*"],
          ExposeHeaders: [],
          MaxAgeSeconds: 3000,

Enter fullscreen mode Exit fullscreen mode

Then run the script with node:

node cors.js
Enter fullscreen mode Exit fullscreen mode

If everything works well, you should see the following logged in the console:

  '$metadata': {
    httpStatusCode: 200,
    requestId: undefined,
    extendedRequestId: undefined,
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
Enter fullscreen mode Exit fullscreen mode

And that's it, your CORS issue should be resolved now.

If you have any questions or just want to connect, follow me on Twitter.

Top comments (1)

geekyayush profile image
Ayush Somani

Damn! Thanks man.

Create an Account! The only reason people scroll to the bottom...  
is because they want to read more.

Create an account to bookmark, comment, and react to articles that interest you.