CDN URL configuration generates malformed asset URLs

Hi !

We’re experiencing an issue with OpenedX’s CDN configuration feature where setting a CDN URL in the admin interface results in malformed asset URLs being generated.

Expected behavior:
When configuring a CDN URL (e.g., https://cache.domain.com) for asset delivery, the system should generate clean URLs like:
https://cache.domain.com/asset-v1:OpenedX+DemoX+DemoCourse+type@asset+block@image.webp

Actual behavior:
The system generates malformed URLs that include both the LMS domain and CDN domain:
https://domain.com//cache.domain.com/asset-v1:OpenedX+DemoX+DemoCourse+type@asset+block@image.webp
Notice the double slash and the CDN URL being appended as a path to the LMS domain instead of replacing it entirely.

Additional context:
This appears to be a URL generation bug in the asset handling code. The CDN feature also seems to have limitations - once configured, it cannot be easily updated or removed without database manipulation, and even then, cached references may persist.

Has anyone else encountered this issue with CDN URL generation? Any insights into the correct way to configure CDN support for assets would be greatly appreciated.

Hi @aa-perseus
Have you looked at the documentation for Enabling a CDN for Course Assets? In particular step 4 sounds like it might be relevant here (if you’ve incorrectly formed your config.)

After you configure your CDN, follow these steps.

  1. Sign in to the Django administration console for your base URL. For example, http://{your_URL}/admin.
  2. In the Static_Replace section, next to Asset base url configs, select Add.
  3. Select Enabled.
  4. Enter the hostname for your CDN provider.For example, if you were using CloudFront, this would look something like d37djvu3ytnwxt.cloudfront.net.Be sure not to include the scheme (http:// or https://) when you specify the hostname.
  5. Select Save.

I’m not particularly familiar with using CDN’s here so just doing some guesswork, but from what I can tell here it looks like it should be correct in the code (at least nothing stands out to me immediately)