wow what a ride this was. i basically reconfigured my whole Cloudfare R2 object storage and Discourse instance, and i think this bug is legit for R2. when i fixed my cloudflare dns record and rebuilt the instance so that DISCOURSE_CDN_URL actually pointed to it, it borked a bunch of other stuff like translation strings and threw multiple errors in the console including some CORS errors. it led me down many rabbit holes today. so i guess using DISCOURSE_CDN_URL seems incompatible with Cloudflare R2. (this was very weird - when i originally setup my original dns entry, i had incorrectly entered the cdn.mysite.com dns record so that it was resolving as cdn.mysite.com.mysite.com). setting DISCOURSE_CDN_URL correctly seems incompatible with Cloudflare R2 object storage. there may be some other stuff i’m not fully understanding here.
anyways, when i rebuild with my PR branch it is all fixed because it wraps the assignment in Discourse.store.cdn_url() so that custom emojis uploads obey the same S3 CDN routing and fallback logic as standard post image uploads.
i reopened the PR and edited the description. but i guess if Discourse team chooses not to merged it, that is fine because the theme component fixes the issue at the client level. Note the PR fix should only affect R2 object storage configurations for custom emoji and not other regular S3 compatible like AWS.