r2 multipart upload from the browser fails cors preflight but curl works fine R2
Presigned PUT straight from the browser to R2, signing with aws4fetch in a Worker. Browser says:
Access to fetch at 'https://...r2.cloudflarestorage.com/...' has been blocked by CORS policy: Response to preflight request doesn't pass access control check
The bucket CORS rules have AllowedOrigins: ["*"] and AllowedMethods: ["PUT"]. The exact same signed URL works from curl. Single-part uploads under 5 MB were fine, this started when I switched to multipart for large files.
@seedstart_sim · last mo. · 3 replies
curl does not send a preflight, so "it works in curl" tells you nothing at all about CORS. Useful for checking the signature, useless for checking this.
The preflight is failing on headers, not on origin or method. The browser sends
Access-Control-Request-Headerslisting everything your request will carry, and multipart signing addsx-amz-content-sha256,x-amz-date,authorizationandcontent-typeon top of whatever else. If those are not inAllowedHeaders, the preflight is rejected before the upload is even attempted.Then the one that catches people immediately after they fix that:
Without it every part upload succeeds and the completion call fails, because JavaScript cannot read the ETag header it needs to send back for each part. It looks like a completely different bug and it is the same config block.
Also add
POSTto AllowedMethods — multipart initiate and complete are POSTs, not PUTs.Reply
Report
@boundaries_bo · last mo.
ExposeHeaders was it, second half exactly as described — preflight passed, all six parts uploaded, complete threw because every ETag came back null. Would not have connected those two things on my own.
Reply
Report
@ridgeline_rowan · last mo.
Worth knowing CORS rule changes take a minute or two to propagate, so do not conclude your fix failed after one immediate retry. I have reverted two correct fixes that way.
Reply
Report