Mastering CORS in Nginx: Common Errors and Precise Fixes
This guide explains the fundamentals of CORS, walks through typical misconfigurations such as HeaderDisallowedByPreflightResponse, Nginx header ordering, and Origin‑Credentials conflicts, and provides complete Nginx examples to reliably enable cross‑origin requests.
As web applications grow more complex, Cross‑Origin Resource Sharing (CORS) becomes essential for front‑end and back‑end interactions, but configuring it correctly on a server can be tricky. This article first clarifies CORS basics, then details three frequent problems and their step‑by‑step solutions, and finally presents a full Nginx configuration that addresses all of them.
Understanding CORS Basics
CORS is a browser‑enforced mechanism that lets servers specify which origins may access resources. The browser classifies requests as simple requests or preflight requests. Simple requests follow standard HTTP rules and do not trigger a preflight. Preflight requests (using the OPTIONS method) occur when the request uses non‑standard methods such as PUT, DELETE, or custom headers, allowing the browser to ask the server for permission before sending the actual request.
Successful cross‑origin calls require the server to return appropriate headers, including Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers.
Common Issues and Solutions
1. HeaderDisallowedByPreflightResponse
This error appears when the request includes headers that are not listed in Access-Control-Allow-Headers. To fix it, add every custom header used by the client, for example:
add_header 'Access-Control-Allow-Headers' 'Authorization, X-Custom-Header, Content-Type';After the server includes these headers in its preflight response, the actual request proceeds without blockage.
2. Nginx CORS Header Order
When Nginx acts as a reverse proxy, placing add_header directives before proxy_pass can cause the upstream application to overwrite the CORS headers, resulting in failed requests. The fix is to ensure that all add_header statements appear after proxy_pass.
server {
listen 80;
location /api/ {
proxy_pass http://backend_server;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
return 204;
}
}
}3. Conflict Between Access-Control-Allow-Origin and Access-Control-Allow-Credentials
The CORS specification forbids using a wildcard ( *) for Access-Control-Allow-Origin when Access-Control-Allow-Credentials is set to true. Browsers require an explicit origin in this case. The correct configuration is:
add_header 'Access-Control-Allow-Origin' 'https://example.com';
add_header 'Access-Control-Allow-Credentials' 'true';Complete Nginx Configuration Example
The following snippet combines all the fixes into a single, ready‑to‑use server block:
server {
listen 80;
location /api/ {
add_header 'Access-Control-Allow-Origin' 'https://your-frontend-domain.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://your-frontend-domain.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
return 204;
}
proxy_pass http://backend_server;
}
}This configuration ensures that preflight requests receive the proper CORS headers, that credentials are allowed only for a specific origin, and that the upstream service does not overwrite the headers.
Conclusion
By understanding CORS fundamentals and addressing typical pitfalls—missing header allowances, incorrect Nginx directive ordering, and Origin/Credentials conflicts—developers can reliably enable cross‑origin support for their web applications, avoiding common configuration‑related failures.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development & AI Practice
DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
