Cloudflare Images direct upload CORS problem

I’m trying to upload a file from the browser using the direct_upload endpoint which returns an upload URL.

Unfortunately when trying to upload via XHR from the browser I’m getting this strange CORS error:

Access to XMLHttpRequest at '' from origin '' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

The JS code that uploads is essentially this with some added event handlers:'POST', url);

The file is obtained from an <input type="file"> element.

I’m using XHR instead of fetch because I need to monitor the upload progress to be able to display a progress bar. Fetch doesn’t have support for monitoring upload progress. See these two issues for more info about this:

Check out these previous posts

1 Like

Thanks. I had seen those posts but since the only solution involved using fetch I discarded it.

Looking at it in more detail the solution was to send multipart/form-data instead of the straight file with content type image/jpeg.

So I did:

const formData = new FormData();
formData.append('file', file);

And that finally worked.

Now I understand the issue. The server CORS settings don’t allow any other value for the content-type header than multipart/form-data. Not the best way to communicate an error with a user if you ask me.

It’s really confusing the docs don’t clarify this. The only example is a cryptic HTML form.

It was very, very painful to get it to work! I tried using axios, which is the lib I use for all my api requests and could not get it to work with axios. Eventually I used fetch and it worked - who knows why.

Here’s the code I’m currently using:

const formData = new FormData()
formData.append('file', actualFile, 'filename')

const uploadResult = await fetch(uploadUrl, {
    method: 'post',
     body: formData
const result = await uploadResult.json()

I hope this spares you some time.

What “got” me was that I looked at the example on and I named the parameter I appended “myFile”. After changing the name from “myFile” to “file” it worked fine. I wish the error returned was “Bad Request: Missing parameter named ‘file’” instead of “Bad request: Error parsing form fields.” That would have saved me a couple of hours of frustration.