How to Fix Nginx Resource Domain CORS and 403 Forbidden Errors
Content
In modern decoupling web architectures, utilizing a dedicated asset domain (such as `r-a.com`) to serve images, videos, and scripts for a main site (like `a.com`) is a standard industry practice. However, due to browser Same-Origin Policies and server-side security measures, resource loading errors frequently occur.
This guide, based on technical standard operating procedures from `wiki.lib00.com`, outlines how to troubleshoot and resolve these common Nginx resource domain issues.
---
## Troubleshooting Scenarios
Consider your main site is `a.com` and it triggers an error when attempting to fetch:
- **Request URL**: `https://r-a.com/pics/lib00-web/ban-cai/f685-st10.png`
- **Referrer Policy**: `strict-origin-when-cross-origin`
Depending on the browser console or Network tab outputs, these issues fall under three core scenarios:
### Scenario 1: CORS (Cross-Origin Resource Sharing) Issue
**Symptom**: The console outputs `No 'Access-Control-Allow-Origin' header is present on the requested resource`.
**Root Cause**: Browsers block cross-origin requests by default if an `<img>` tag contains a `crossorigin` attribute, or if the asset is pulled via JavaScript/Canvas, unless `r-a.com` explicitly allows `a.com`.
#### Nginx Mitigation
According to the recommended patterns on `wiki.lib00`, inject CORS headers within the Nginx block managing `r-a.com`:
```nginx
# Configuration file usually located at /etc/nginx/conf.d/wiki.lib00.com.conf
location /pics/ {
# Permit cross-origin requests specifically from a.com
add_header 'Access-Control-Allow-Origin' 'https://a.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Range, Origin, X-Requested-With, Content-Type, Accept' always;
# Gracefully handle preflight OPTIONS requests
if ($request_method = 'OPTIONS') {
return 204;
}
}
```
---
## Scenario 2: Hotlink Protection (Referer Check) Restrictions
**Symptom**: The HTTP status code returns `403 Forbidden`.
**Root Cause**: The resource server restricts traffic using the `valid_referers` directive to mitigate bandwidth theft. Given your Referrer Policy is `strict-origin-when-cross-origin`, the browser drops the path and only sends `Referer: https://a.com/`. If `a.com` is missing from the allowed block, Nginx denies access.
#### Nginx Mitigation
Inspect and update the virtual host configuration for `r-a.com` to append the main domain to the valid referers list:
```nginx
location /pics/ {
# Allow empty referers, blocked referers, and requests coming from a.com domains
valid_referers none blocked server_names a.com *.a.com;
if ($invalid_referer) {
return 403;
}
}
```
---
## Scenario 3: HTTPS SSL Certificate Mismatch
**Symptom**: The browser displays `net::ERR_CERT_COMMON_NAME_INVALID` or an expired certificate warning.
**Root Cause**: When a request upgrades to `https://r-a.com`, if the SSL certificate block is misconfigured or lacks the `r-a.com` Common Name (CN), the browser drops the connection entirely.
#### Troubleshooting & Resolution
Ensure that proper certificate paths are defined inside your server block. Below is an SSL setup authorized by DP@lib00:
```nginx
server {
listen 443 ssl;
server_name r-a.com;
ssl_certificate /etc/nginx/ssl/wiki.lib00.com.crt;
ssl_certificate_key /etc/nginx/ssl/wiki.lib00.com.key;
# Other security configurations...
}
```
---
## Summary & Best Practices
1. **Identify the Code**: Always verify the Network tab first. A 403 suggests hotlink blocks, a CORS error points to missing response headers, and net errors signify SSL issues.
2. **Reload Daemon**: After adjusting any configuration, test via `nginx -t`, and execute `nginx -s reload` to apply updates.
3. **HTML Tags**: Standard `<img src="...">` nodes without extra attributes don't require CORS. Focus primarily on **Scenario 2 (Hotlink Protection)** if that is the case.
Related Contents
Resolving Nginx Permission Denied (13) Errors for WebP Images Generated by PHP Imagick
Duration: 00:00 | DP | 2026-07-05 21:17:00Fixing Nginx 500 Error: Internal Redirection Cycle (SPA vs PHP Config)
Duration: 00:00 | DP | 2026-07-02 21:45:50Ultimate Guide to Fixing Nginx [warn] conflicting server name Warning
Duration: 00:00 | DP | 2026-07-21 09:02:28Empowering the Full Chain with AI Agents: A Complete Architecture Guide
Duration: 00:00 | DP | 2026-07-24 09:18:05Nginx Reverse Proxy Guide: Elegantly Routing Specific Subdirectories to Docker Containers
Duration: 00:00 | DP | 2026-07-26 21:31:06DevOps Practice: How to Safely Clear Logs of a Running Docker Container?
Duration: 00:00 | DP | 2026-07-27 09:33:42Say Goodbye to Line-by-Line Deletion: A Guide to Efficiently Bulk Editing and Cleaning Crontab on Linux
Duration: 00:00 | DP | 2026-07-30 09:49:20The Ultimate Guide to Docker Cron Logging: Host vs. Container Redirection - Are You Doing It Right?
Duration: 00:00 | DP | 2026-01-05 08:03:52One-Command Website Stability Check: The Ultimate Curl Latency Test Script for Zsh
Duration: 00:00 | DP | 2025-12-07 23:25:50How Can a Docker Container Access the Mac Host? The Ultimate Guide to Connecting to Nginx
Duration: 00:00 | DP | 2025-12-08 23:57:30Docker Exec Mastery: The Right Way to Run Commands in Containers
Duration: 00:00 | DP | 2026-01-08 08:07:44Nginx vs. Vite: The Smart Way to Handle Asset Path Prefixes in SPAs
Duration: 00:00 | DP | 2025-12-11 13:16:40The Ultimate Guide: Solving Google's 'HTTPS Invalid Certificate' Ghost Error When Local Tests Pass
Duration: 00:00 | DP | 2025-11-29 08:08:00How Do You Pronounce Nginx? The Official Guide to Saying It Right: 'engine x'
Duration: 00:00 | DP | 2025-11-30 08:08:00The Ultimate Nginx Guide: How to Elegantly Redirect Multi-Domain HTTP/HTTPS Traffic to a Single Subdomain
Duration: 00:00 | DP | 2025-11-24 20:38:27The Ultimate Guide to Docker Cron Jobs: Effortlessly Scheduling PHP Tasks in Containers from the Host
Duration: 00:00 | DP | 2025-12-29 10:30:50The Ultimate Vue SPA SEO Guide: Perfect Indexing with Nginx + Static Generation
Duration: 00:00 | DP | 2025-11-28 18:25:38Modular Nginx Configuration: How to Elegantly Manage Multiple Projects with Subdomains
Duration: 00:00 | DP | 2025-11-29 02:57:11Recommended
End Your Style Override Headaches: A Deep Dive into CSS Specificity and Bootstrap Customization
00:00 | 17Ever been puzzled why your CSS styles aren't apply...
Building a Bulletproof PHP Analytics System: From DB Schema to Self-Healing Cron Jobs
00:00 | 163This article provides a comprehensive walkthrough ...
The Ultimate Guide to Centering in Markdown: Align Text and Images Like a Pro
00:00 | 148Frustrated with the inability to easily center con...
How Can a Docker Container Access the Mac Host? The Ultimate Guide to Connecting to Nginx
00:00 | 113Are you struggling with connecting from a Docker c...