Setting up CORS for other websites to stream live radio from your Liquidsoap/HLS Streaming Server.
This article is about NGINX only.
I first encountered this issue on April 16-17, 2025.
On May 24, 2025, I resolved the issue for Local Streams (Within my Network)
(Change demo.domain.com to your domain)
For Local, navigate to the following folder
/etc/nginx/nginx.conf
Copy
Search Site
Search Google

Add the following to the http section
[CORS]
CFFCS | CarrzSynEdit: | CMD (Windows Command Prompt) | L (Linux)
 http {
        add_header 'Access-Control-Allow-Origin' 'https://demo.domain.com' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}

And then, when I tested it outside the network, it gave me the CORS error again.
So, on July 5, 2025, I figured out what I needed to do to get it to work outside the network.
I copied the code from above and started placing it in different files, restarting NGINX until it worked.
To have it work from outside your network.
Navigate to the following folder.
/usr/local/nginx/conf/nginx.conf
Copy
Search Site
Search Google

Add the following to the Server {9443} section, along with your SSL Information.
[nginx/nginx.conf]
CFFCS | CarrzSynEdit: | CMD (Windows Command Prompt) | L (Linux)
 server {
      listen 9443 ssl;
      listen [::]:9443 ssl;

      server_name stream.domain.com/;

        add_header 'Access-Control-Allow-Origin' 'https://demo.domain.com' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
      ssl_certificate /etc/letsencrypt/live/stream.domain.com//fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/stream.domain.com//privkey.pem;
      add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

      #Configures the publicly served root directory
      #Configures the index file to be served
      root /srv/web/Inetpub/wwwroot/stream.domain.com/;
      index index.html index.htm;
      location /hls/ {
      root /srv/web/Inetpub/wwwroot/stream.domain.com;

Updated on [February 25, 2026].
It has been a summer since I last had the streaming server running, so I had forgotten a few things along the way.
While getting the list stream going, I ran into the dreaded [CORS] error again.
I found out that I needed to update all the files that had the URL to allow the stream to be received.
After changing the two locations above, I was still receiving the same [CORS] error pointing to the old subdomain that I no longer use.
I rebooted the Linux server.
After getting back up, the [CORS] error was still there.
I did a quick Google search to find out which files can be edited in [NGINX], and one of the locations that I failed to mention in this article, and had forgotten about myself.
nano /etc/nginx/sites-available/stream.domain.com
Copy
Search Site
Search Google

Inside this file is the same as the above /usr/local/nginx/conf/nginx.conf
Copy
Search Site
Search Google

Update the file with this. (Change to the actual domain you want to allow access to the stream.)
[sites-available/stream.domain.com]
CFFCS | CarrzSynEdit: | CMD (Windows Command Prompt) | L (Linux)
server {
      listen 9443 ssl;
      listen [::]:9443 ssl;

      server_name stream.domain.com/;

        add_header 'Access-Control-Allow-Origin' 'https://demo.domain.com' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
      ssl_certificate /etc/letsencrypt/live/stream.domain.com//fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/stream.domain.com//privkey.pem;
      add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

      #Configures the publicly served root directory
      #Configures the index file to be served
      root /srv/web/Inetpub/wwwroot/stream.domain.com/;
      index index.html index.htm;
      location /hls/ {
      root /srv/web/Inetpub/wwwroot/stream.domain.com;