Error in direct creator's tokenlized url using tus

I am following the Direct creator uploads · Cloudflare Stream docs to create a tokenized URL for tus.
I am not sure what should I put in Upload-Metadata so I did not include it. I did include Upload-Length which I set to size of my file in bytes. the API returns 200 with header.location =

however, when I use tus demo to test the url, I had no luck, it keep saying error without more information, as shown in the screenshot below

Screen Shot 2021-08-23 at 17.32.41

how should I continue to investigate the issue?

@cheng Do you have a way for us to replicate the problem you’re facing?

should I just send you a tokenized link?

Maybe a webpage where I can try an upload? I don’t see any issues on the server side so far, so maybe the issue could be on the web page javascript?

I see, the page I try to use is tus demo (

I encounter the CORS error when doing my own server, so I got back to the documentation and got the error when following to use tus demo.

then I searched more and found Getting CORS using tus (Direct creator uploads) - #16 by hart.wl , will try the suggestion there.

To confirm, should I do a tus rquest to my server and my server just return a 201 and set Location?

1 Like

Yes! That’s right! Let us know if it works for you.

where should I send the size of the file been uploaded? I can do it from browser and include the post request, but I am not sure if that’s the preferred way.

If you look at the example worker script (, this line specifically contains the length:

  'Upload-Length': request.headers.get('Upload-Length'),

So the file length is passed as a header value when calling the Stream API to request a URL token

got it. I have another question, how do I set ‘expiry’ for Upload-Metadata?
I used golang so I just set use now.Add(time.Hour * 1).String() , in my case it’s 2021-08-31 14:42:15.575272 +0800 CST m=+3606.099049330 , and base64 is MjAyMS0wOC0zMSAxNDo0MjoxNS41NzUyNzIgKzA4MDAgQ1NUIG09KzM2MDYuMDk5MDQ5MzMw
it was working ok when I use non-tus direct upload and pass as JSON request body,
however, when I convert to base64 and put it in the header, I got metadata the error message

    "messages": [
            "code": 10034,
            "message": "Malformed field: expiry"

I figured myself, use RFC3399 seems working.

I do have another question, which is probably related to uppy, my own server is using a bear token for authorization, however, when uppy post to upload url, it’s including the token as well, and the request would fail with ’ Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.’ How can I remove the header in the second request?

Sorry might not have the fullest context to help but maybe you can handle the interaction between the client side and your server separately using a fetch() request from the requests Uppy is making? That way you don’t have to send headers with Uppy?
Stream deliberately doesn’t include the authorization header in the CORS preflight response to make sure no tokens are sent from the client side to Cloudflare accidentally.

I am not sure if I follow your suggestion, from my test, Uppy only works when the server did a 201 redirect. If I use 200 and make another request from Uppy then upload won’t work.
my client code now look like

  uppy.use(Tus, {
    endpoint: 'http://localhost:5000/api/coach/streams/upload',
    chunkSize: 1024 * 1024 * 40,

how do I use fetch?

The hack I can think of is return a one-time signed URL from my server in another request, the signed url itself does not need a bearer token for authorization so Uppy would use that. But it seems too much hassle. one more request and multiple previous headers need to be in URL parameter.