XMLHttpRequest file upload to Spaces fails due to CORS issue

I’m trying to upload a file to Spaces using XMLHttpRequest with a pre-signed url generated by the boto3 Python library. I’m using the v2 signature type as the AWS v4 signature is not supported (yet). (

Performing an upload from the command line using the pre-signed url is working fine. However when doing a PUT request through an XMLHttpRequest object in Javascript I’m getting an CORS related error (“No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://XXX’ is therefore not allowed access”)

I have enabled CORS policies for this particular host like this:


The preflight OPTIONS http request actually returns the appropriate headers like this:

Date:Wed, 15 Nov 2017 15:41:08 GMT
Strict-Transport-Security:max-age=15552000; includeSubDomains; preload

In the actual PUT request which upload the file payload the headers returned by the Digital Ocean does not return the required Acces-Control-Allow-Origin header though:

Date:Wed, 15 Nov 2017 15:41:08 GMT
Strict-Transport-Security:max-age=15552000; includeSubDomains; preload

This finally results in a 403 Forbidden error. I’m really in the dark on this one, any insight would be highly appreciated…


Submit an answer
You can type!ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Accepted Answer

@krksgbr what a coincidence, I was just about to post the solution to my own question. It turned out not to be a CORS issue at all (sorry about that DO), but related to the way the file was sent through Javascript. Apparently you have to wrap your file in a Blob object and not send it as a raw file (e.g. xhr.send(upload_file)) or through the FormData interface.

I managed to upload a file like this:

var blob = new Blob([upload_file], {type: f.upload_file}); var xhr = new XMLHttpRequest();‘PUT’, v2_presigned_url); xhr.send(blob);

i have set Header name ‘Access-Control-Allow-Origin’ and Origin * in spaces setting. My problem is that i am not getting header while accessing ‘’ in postman or chrome. What is the issue?

@al3x5 @krksgbr @johngannon

Hey, did you find a solution/explaination ? I’m stuck on this problem too, thanks

It is simple to solve! Just use ‘s3cmd’ command line tool:

s3cmd setcors file-with-bucket-cors.xml s3://BUCKETNAME

It is one shot config, after this, all will work perfectly!

Good luck!

@al3x5 did you ever manage to find a solution? I am experiencing the same exact problem. thanks!

@al3x5 thanks Can you email me (jgannon @ do dot co) with all of the details that I would need to pass on to our engineering team? I want to make sure they have a full picture of what you’re experiencing. Thanks for taking the time to give this feedback.

@al3x5 we just(yesterday) shipped a UI for CORS config in the DO Control Panel. Please take a look and if you are still running into challenges, let us know. Thanks for all of the feedback.

Unfortunately it’s not working. I wasn’t aware of the s3cmd command but that seems to work too. I managed to set CORS policies before using the Boto3 Python library. The strange this is, the preflight OPTIONS request is actually returning the appropriate headers but things go wrong upon the upload PUT request. It sounds like some kind of server misconfiguration at DigitalOcean to me as uploading from command line works perfectly, although this doesn’t require CORS headers to be returned. I created a ticket at DigitalOcean and they keep telling me to be patient but it’s been about two weeks now and I’m losing confidence :-/