Operations 13 min read

Resolving CORS Issues with Nginx Proxy Configuration: A Step‑by‑Step Guide

This article explains how to diagnose and fix common CORS problems when a front‑end site on port 8080 accesses a back‑end service on port 59200 by configuring Nginx as a proxy, detailing the required response headers, handling preflight requests, and providing complete example configurations.

Architect's Guide
Architect's Guide
Architect's Guide
Resolving CORS Issues with Nginx Proxy Configuration: A Step‑by‑Step Guide

When a front‑end application (e.g., http://localhost:8080) requests an API served at http://localhost:59200, browsers enforce the Cross‑Origin Resource Sharing (CORS) policy. If the back‑end does not send the proper CORS headers, the request is blocked.

The four main CORS response headers are:

Access-Control-Allow-Origin – specifies the allowed origin.

Access-Control-Allow-Headers – lists permitted custom request headers (checked during the preflight request).

Access-Control-Allow-Methods – enumerates allowed HTTP methods (also checked during preflight).

Access-Control-Allow-Credentials – indicates whether cookies can be sent with cross‑origin requests.

Many tutorials suggest simply adding these headers in Nginx, but real‑world scenarios often require more precise handling because the headers may be missing, duplicated, or not applied to OPTIONS (preflight) requests.

Case 1 – Missing Access-Control-Allow-Origin : The preflight response lacked this header, causing the error “No Access‑Control‑Allow‑Origin header is present”. Adding the header in the Nginx location block resolves the issue, but the configuration must be applied to the OPTIONS request as well.

server {
    listen 22222;
    server_name localhost;
    location / {
        add_header Access-Control-Allow-Origin 'http://localhost:8080';
        proxy_pass http://localhost:59200;
    }
}

Case 2 – Preflight request does not return a 2xx status: The browser expects a successful OPTIONS response (usually 204). Adding an if ($request_method = 'OPTIONS') block that returns 204 fixes the problem.

if ($request_method = 'OPTIONS') {
    return 204;
}

Case 3 – Missing Access-Control-Allow-Headers (e.g., authorization ): The preflight request includes a custom header that the server does not whitelist. Adding the missing header inside the OPTIONS block solves it.

if ($request_method = 'OPTIONS') {
    add_header Access-Control-Allow-Headers 'authorization';
    return 204;
}

Case 4 – Unsupported HTTP method (e.g., PUT): By default only GET and POST are allowed. Adding the required method to Access-Control-Allow-Methods (or using * ) lets the browser proceed.

add_header Access-Control-Allow-Methods 'PUT';

Case 5 – Multiple Access-Control-Allow-Origin values: When both Nginx and the back‑end set this header, the response contains duplicate values (e.g., "*, http://localhost:8080"), which browsers reject. Ensure only one source sets the header.

To avoid the above pitfalls, a robust Nginx configuration separates handling of OPTIONS requests from normal requests and uses the always flag to guarantee header inclusion:

server {
    listen 22222;
    server_name localhost;
    location / {
        if ($request_method = 'OPTIONS') {
            add_header Access-Control-Allow-Origin 'http://localhost:8080';
            add_header Access-Control-Allow-Headers '*';
            add_header Access-Control-Allow-Methods '*';
            add_header Access-Control-Allow-Credentials 'true';
            return 204;
        }
        if ($request_method != 'OPTIONS') {
            add_header Access-Control-Allow-Origin 'http://localhost:8080' always;
            add_header Access-Control-Allow-Credentials 'true' always;
        }
        proxy_pass http://localhost:59200;
    }
}

In summary, solving CORS issues with Nginx requires adding the correct headers, ensuring they are present on both preflight and actual requests, returning a successful status for OPTIONS, and avoiding duplicate header definitions. Choose either Nginx or the back‑end to handle CORS, but not both.

ProxyWeb DevelopmentCORSNginxhttp headersPreflight
Architect's Guide
Written by

Architect's Guide

Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.