Backblaze B2 with Transform Rule fails on some browsers, not others

Hey there!

So I use a Backblaze B2 bucket to serve JSON files that don’t change very often. I serve this on an api subdomain on my domain.

Here’s an example URL: api.brawlapi.com/v1/maps

This URL loads and serves content just fine if I request it via Postman, but fails (404 file not found) when requested from Brave/Chrome.

To provide more insight on what I use and how, I followed these two tutorials below:

Here’s a page rule for the subdomain:

The transform rule (exception for two paths as I use workers on those)

Here’s a DNS record for this subdomain

The bucket on Backblaze B2

Here’s the file in this bucket I’m requesting

The issue is this! Whenever I request this file via a browser, in my case Brave / Chrome, it fails this way
image

However if I request the same URL from Postman, it serves the contents of the file as it should

I’m very lost in how I should approach this issue or how I should go around fixing this. I have no idea why this fails, maybe this is obvious to you. I would welcome some tips and I’m happy to provide anything else that might reveal this issue I missed. It’s not just me, but multiple people using my service who experience this same issue. In the past I used a Wasabi as an S3 bucket for the same purpose and it worked well and never had these issues, but a Transform Rule wasn’t necessary. That’s why I expect this is probably related to the Transform Rule? Looking for people who could help debug this.

Have you checked your CORS settings? :thinking:

Recently I’ve used that setup too and it worked, but on files and was not using “query” in Transform Rules, despite I’ve used Worker too.

api.brawlapi.com/v1/maps → loads fine, JSON output on my end using Mozilla Firefox

If you are using Cache Everything, may I ask have you tried using a different Web browser, or tried clearing your Web browser cache?
How about using a Private window (Incognito mode) or a VPN connection if possible?
Is it the same behaviour on your mobile phone (4G LTE, mobile data, cellular)?

Same on my end when using Chrome.

UPDATE 2: Now it says 404 even on Firefox → when I see cf-cache-status: HIT

My CORS settings are as below, this has been the case since I basically started using this bucket on Backblaze:

I tried clearing cache or using different browsers, no idea where this originates.

Yes, it typically fails in browsers but works if requested programmatically / Postman / code / XHR.

This I can’t explain, very strange behaviour.

Hi - I wrote the ‘free image hosting’ blog post, so I was quite keen to figure out why this isn’t working for you.

tl;dr - Chrome is trying to use a new web feature called Signed Exchanges (SXGs); API clients almost certainly won’t try to do the same, so you don’t need to worry about it.

Read on if you want to understand what’s happening, and make the URL work in Chrome…

I tried the same query for https://api.brawlapi.com/v1/maps from Safari, and it worked just fine. I tried it from curl on the command line, and it worked there, too. I tried it from Chrome, and it failed with a 404. Strange.

Looking at the network request in the Chrome and Safari developer tools, I could see that the HTTP request headers included by the two browsers were quite different. A few minutes trying the different headers with curl narrowed the culprit down to Accept.

Chrome sets the Accept header to:

text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

Safari sets it to:

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

More testing revealed that the issue is with application/signed-exchange. Including it in the Accept header makes the request fail:

% curl -I https://api.brawlapi.com/v1/maps -H 'accept: application/signed-exchange'
HTTP/2 404 
date: Tue, 08 Mar 2022 18:35:11 GMT
content-type: application/json;charset=utf-8
content-length: 94
...

While, with curl's default Accept header:

% curl -I https://api.brawlapi.com/v1/maps                                         
HTTP/2 200 
date: Tue, 08 Mar 2022 18:36:17 GMT
content-type: application/json
content-length: 334908
...

Now, the problem isn’t that it’s the wrong media type. We can specify pretty much anything in Accept and it will return the same JSON response:

% curl -I https://api.brawlapi.com/v1/maps -H 'accept: image/png'                  
HTTP/2 200 
date: Tue, 08 Mar 2022 18:37:57 GMT
content-type: application/json
content-length: 334908
...

% curl -I https://api.brawlapi.com/v1/maps -H 'accept: wicky/wacky'
HTTP/2 200 
date: Tue, 08 Mar 2022 18:50:03 GMT
content-type: application/json
content-length: 334908

It turns out that application/signed specifies Signed Exchanges (SXGs), a new web delivery mechanism. Cloudflare has beta support for SXGs. I suspect that, in trying to create its SXG, Cloudflare is hitting a non-existent URL at B2 and returning that failure to the browser. If you have enabled Automatic Signed Exchanges (SXGs), try turning it off and see if the URL works correctly in Chrome.

In any case, as I mentioned up at the top, assuming that it’s an API client that will be hitting this URL, it’ll never encounter this error, so you could just ignore it.

2 Likes

Hey @metadaddy, thank you for your reply!

It seems that this is exactly the issue and after turning Automatic Signed Exchanges off from the dashboard, these URLs now load fine and as expected. I will report this issue to Cloudflare with this forum post. Maybe for the time being you could include it in your blog post on Backblaze for people experiencing the same issue? Anyways, huge thanks.

2 Likes

Hi @henrichvv - great to hear this worked for you. I added a note to the blog post as you suggested:

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.