Fix CORS errors instantly

Bypass CORS errors and unblock your API requests.
Corsfix adds the right CORS headers so your browser can access data from any API.

ERROR
Access to fetch at 'https://my.api/' from origin 'https://www.yourdomain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

fetch('https://my.api/')

Used by thousands of developers worldwide, including at these companies

One line change, zero CORS errors

Add the proxy URL before your target API and fetch without CORS errors. Find more usage details in our documentation.

// Add Corsfix URL before the API
// https://proxy.corsfix.com/? + https://api.example.com/data
fetch("https://proxy.corsfix.com/?https://api.example.com/data")
.then((response) => response.json())
.then((data) => console.log(data));

Works Anywhere

Corsfix works on any platform and any tech framework out there. You can find your specific use case in our code examples and platform integration.

Honestly, working with Corsfix has been incredible, the level of support is top-notch, and using Corsfix has improved the entire user experience for our Figma plugin.

Kyle Conrad's avatar
Kyle Conrad

Lead Product Designer at Taco Bell

I've loved the way you're really trying to satisfy users' requests to make Corsfix an outstanding product. This is the aptitude I really like to see around me and my team.

Emanuele Luchetti's avatar
Emanuele Luchetti

Co-founder and CTO at tuOtempO

I've tried a couple more proxy services but they didn't work as I was expecting, or at all. With that said I was quite surprised at how easy it was to use Corsfix and how well it's documented.

Prem Daryanani's avatar
Prem Daryanani

Web Developer

Frequently Asked Questions

How do I fix CORS error?

The fastest way to fix a CORS error is to use a CORS proxy like Corsfix. Add the proxy URL before your target API endpoint, and the proxy will forward your request server-side and return the response with the correct Access-Control-Allow-Origin header attached:

fetch("https://proxy.corsfix.com/?https://api.example.com/data")
  .then(response => response.json())
  .then(data => console.log(data));

This works because CORS is only enforced by browsers. A proxy makes the request from a server, bypassing the browser's Same-Origin Policy entirely. No backend changes needed.

If you own the API server, you can also fix it by configuring your backend to send the proper CORS headers (covered in a later question). And for local development only, a browser extension can temporarily disable CORS checks — but that won't help your users in production.

What is CORS?

CORS stands for Cross-Origin Resource Sharing. It's a browser security mechanism that controls whether JavaScript running on one website is allowed to request resources from a different website.

An "origin" is defined by three components: the protocol (http vs https), the domain (example.com vs api.example.com), and the port (:3000 vs :8080). If any of these differ between your frontend and the API you're calling, the browser considers it a cross-origin request and enforces CORS rules.

For example, a frontend at http://localhost:3000 calling an API at http://localhost:8080 is cross-origin because the ports are different. The browser will block the response unless the server explicitly allows it by sending the right CORS headers.

What is the Same-Origin Policy and why does it exist?

The Same-Origin Policy (SOP) is a fundamental browser security rule that prevents a website from reading data returned by another website. CORS is the mechanism that allows servers to selectively relax this restriction.

SOP exists to prevent Cross-Site Request Forgery (CSRF) attacks. Here's how such an attack would work without SOP:

  1. You log into your bank at bank.com. The browser stores your session cookie.
  2. You visit a malicious site, evil-site.com.
  3. That site's JavaScript silently sends a request to bank.com/api/transfer.
  4. Your browser automatically attaches your bank.com cookies to the request.
  5. Without SOP, the attacker could read the response and steal your data — or worse, initiate transactions on your behalf.

The Same-Origin Policy stops this by blocking evil-site.com from reading any response that comes back from bank.com. It's not a bug — it's the browser protecting you.

What actually causes a CORS error?

A CORS error is triggered when the browser makes a cross-origin request but the server's response doesn't include the required CORS headers to permit it. Here's the step-by-step flow:

  1. Your frontend JavaScript at https://myapp.com sends a request to https://api.example.com.
  2. The browser detects this is a cross-origin request (different domains) and adds an Origin: https://myapp.com header.
  3. The server receives the request and processes it. The request actually succeeds on the server.
  4. The server sends back a response — but without an Access-Control-Allow-Origin header.
  5. The browser sees the missing header, blocks your JavaScript from reading the response, and logs a CORS error in the console.

This is an important distinction: CORS doesn't prevent the request from being sent — it prevents your code from reading the response. This is why you might see side effects on the server (like a database record being created) even though the browser shows a CORS error. The request went through; the browser just refused to hand you the result.

What are the common CORS error messages and what do they mean?

Here are the most common CORS errors you'll see in the browser console, and what each one means:

1. "No 'Access-Control-Allow-Origin' header is present on the requested resource"

The server didn't include the Access-Control-Allow-Origin header in its response at all. This is the most common CORS error. Fix it by adding the header on the server side, or use a CORS proxy if you don't control the server.

2. "The 'Access-Control-Allow-Origin' header has a value that is not equal to the supplied origin"

The header exists, but the origin it allows doesn't match your frontend's origin. For example, the server allows https://www.myapp.com but your frontend is running on https://myapp.com (without www). Origins must match exactly — protocol, domain, and port.

3. "Method PUT is not allowed by Access-Control-Allow-Methods in preflight response"

The server accepts cross-origin requests but doesn't permit the HTTP method you're using. The server needs to include the method in its Access-Control-Allow-Methods response header.

4. "Response to preflight request doesn't pass access control check"

The browser sent a preflight OPTIONS request to check permissions, and the server either didn't handle it correctly or returned an error. Make sure your server responds to OPTIONS requests with the appropriate CORS headers and a 200 or 204 status code.

5. "The value of the 'Access-Control-Allow-Origin' header must not be the wildcard '*' when the request's credentials mode is 'include'"

You're sending cookies or an Authorization header with credentials: 'include', but the server responds with Access-Control-Allow-Origin: *. When credentials are involved, the server must specify the exact origin — wildcards are not allowed. The server also needs to include Access-Control-Allow-Credentials: true.

6. "Multiple Access-Control-Allow-Origin headers are not allowed"

The server sent more than one Access-Control-Allow-Origin header. This often happens when CORS is configured in multiple places (both in application code and in a reverse proxy like Nginx). Only one header with a single origin value is allowed.

What is a preflight request?

A preflight request is an automatic OPTIONS request that the browser sends before your actual request to ask the server: "Will you accept this cross-origin request?"

Not all requests trigger a preflight. Simple requests — those using GET, HEAD, or POST with basic content types like application/x-www-form-urlencoded — are sent directly. The browser checks the CORS headers on the response after the fact.

A preflight is triggered when your request is "non-simple," meaning any of the following:

  • You use methods like PUT, PATCH, or DELETE
  • You set Content-Type: application/json (which most modern APIs use)
  • You include custom headers like Authorization or X-API-Key

The preflight flow looks like this:

# 1. Browser sends preflight
OPTIONS /api/data HTTP/1.1
Origin: https://myapp.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

# 2. Server responds with what it allows
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://myapp.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization

# 3. Browser sees permission granted → sends the actual request

If the preflight fails (wrong headers, server error, or no CORS headers), the browser never sends the actual request. This is why some GET requests work fine but POST with JSON breaks — the POST triggers a preflight that the server isn't handling.

Tip: Servers can include Access-Control-Max-Age: 86400 in the preflight response to let the browser cache the result for 24 hours, avoiding repeated OPTIONS requests.

Why does my API request work in Postman but not in the browser?

Because CORS is a browser-only security mechanism. Tools like Postman, cURL, Insomnia, and any server-side code (Node.js, Python, etc.) do not enforce the Same-Origin Policy. They send the request, get the response, and show it to you — no questions asked.

Browsers are different. They check the Access-Control-Allow-Origin header on every cross-origin response and block your JavaScript from reading it if the header is missing or doesn't match your origin.

This is also why a CORS proxy works: instead of your browser making the request directly (browser → API), the proxy makes it server-side on your behalf (browser → proxy → API). Since the proxy-to-API leg is server-to-server, CORS doesn't apply. The proxy then returns the data to your browser with the proper CORS headers attached.

So if your request works in Postman, the API itself is fine — the issue is purely the browser's CORS enforcement on the response.

What are all the ways to fix CORS errors?

There are five approaches, each suited for different situations:

1. Use a CORS proxy (recommended if you don't control the API)

A CORS proxy sits between your frontend and the target API. It forwards your request server-side and returns the response with the correct CORS headers. Corsfix is a managed CORS proxy that works with a one-line code change — just prepend the proxy URL to your API endpoint. This works in both development and production.

2. Configure CORS on your backend (recommended if you own the API)

If you control the server, add the proper Access-Control-Allow-Origin header to your responses. Most backend frameworks have a CORS middleware or package that makes this straightforward (see the next question for code examples).

3. Build your own proxy

You can create a simple server (Node.js, Cloudflare Worker, AWS Lambda, etc.) that receives your frontend's request, forwards it to the target API, and relays the response back with CORS headers. This gives you full control but requires hosting and maintenance.

4. Use the API's client library

Some APIs provide official SDKs or client libraries that handle CORS internally. For example, Google Maps provides a JavaScript client library specifically to avoid CORS issues with their server-side-only endpoints. Check if the API you're using offers one.

5. Browser extension (development only)

Extensions like "CORS Unblock" inject Access-Control-Allow-Origin: * into every response in your browser. This is a quick workaround during development, but it only works on your machine. Your users won't have the extension installed, so this is not a production solution.

How do I configure CORS on my backend?

If you control the API server, here's how to enable CORS in the most popular frameworks:

Node.js / Express

const cors = require('cors');

app.use(cors({
  origin: 'https://yoursite.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  credentials: true
}));

Install the package first with npm install cors.

Python / Flask

from flask_cors import CORS

app = Flask(__name__)
CORS(app, origins=["https://yoursite.com"], supports_credentials=True)

Install with pip install flask-cors.

Python / Django

# settings.py
INSTALLED_APPS = ['corsheaders', ...]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',  # Must be placed high
    'django.middleware.common.CommonMiddleware',
    ...
]

CORS_ALLOWED_ORIGINS = ["https://yoursite.com"]
CORS_ALLOW_CREDENTIALS = True

Install with pip install django-cors-headers.

Java / Spring Boot

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("https://yoursite.com")
            .allowedMethods("GET", "POST", "PUT", "DELETE")
            .allowCredentials(true);
    }
}

Nginx

location /api/ {
    add_header 'Access-Control-Allow-Origin' 'https://yoursite.com' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;

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

Replace https://yoursite.com with your actual frontend origin. If you need to allow multiple origins, see the question below on dynamic origin handling.

Can I use Access-Control-Allow-Origin: * (wildcard)?

Yes, but with important limitations. Setting Access-Control-Allow-Origin: * tells the browser that any origin is allowed to read the response. This is appropriate for truly public APIs where there's no sensitive data involved.

However, the wildcard cannot be used when credentials are involved. If your request includes cookies, an Authorization header, or you set credentials: 'include' in your fetch call, the browser will reject a wildcard origin. This is a hard rule — the server must respond with the exact origin, like Access-Control-Allow-Origin: https://yoursite.com, and also include Access-Control-Allow-Credentials: true.

As a general rule: use the wildcard for public, read-only APIs. For anything involving authentication or private data, specify the exact origin.

How do I allow multiple origins?

The Access-Control-Allow-Origin header only accepts a single value — you can't comma-separate multiple origins. To allow multiple origins, your server needs to dynamically check the incoming Origin request header against a whitelist and reflect the matching origin back.

Here's an example in Express:

const allowedOrigins = [
  'https://myapp.com',
  'https://admin.myapp.com',
  'http://localhost:3000'
];

app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (allowedOrigins.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }
  res.setHeader('Vary', 'Origin');
  next();
});

The Vary: Origin header is critical here. It tells CDNs and caches that the response varies depending on the request's Origin header. Without it, a CDN might cache a response with Access-Control-Allow-Origin: https://myapp.com and serve it to a request from https://admin.myapp.com, which would fail.

Do I fix CORS in the frontend or the backend?

CORS is fundamentally a server-side configuration. The server decides which origins are allowed by setting response headers. No amount of frontend code can override the browser's CORS enforcement.

There are two scenarios:

  • You own the API: Configure CORS headers on your backend. This is the proper, permanent fix.
  • You don't control the API (e.g., a third-party API like a weather service, payment gateway, or public data endpoint): Use a CORS proxy in your frontend code. The proxy makes the request server-side on your behalf, bypassing the browser's restrictions. Corsfix does this with a one-line code change.

A common misconception is trying to fix CORS by adding headers to the request in frontend code. That doesn't work — CORS headers must be on the response from the server.

How do I debug CORS errors?

The browser console only gives you a generic CORS error — for security reasons, it intentionally hides the details. To actually debug, use the Network tab in your browser's DevTools:

  1. Open DevTools (F12 or Ctrl+Shift+I) and go to the Network tab.
  2. Reproduce the failing request.
  3. Find the failed request in the list. If a preflight was sent, you'll see two entries: the OPTIONS request and the actual request.
  4. Click the request and check the Response Headers:
  • Is Access-Control-Allow-Origin present? If not, that's your problem — the server isn't sending it.
  • If it is present, does the value match your frontend's origin exactly? Check for http vs https, www vs non-www, and port numbers.
  • If it's a preflight failure, check the OPTIONS response for Access-Control-Allow-Methods and Access-Control-Allow-Headers.

You can also right-click the failed request, select "Copy as cURL", and run it in your terminal. If the cURL request succeeds, that confirms the issue is browser CORS enforcement, not the API itself.

What is the Vary: Origin header and why does it matter?

When your server dynamically sets Access-Control-Allow-Origin based on the incoming request's origin (instead of using a static value or wildcard), you must include Vary: Origin in the response.

Without it, a CDN or shared cache might serve the wrong cached response. For example:

  1. A request from https://app-a.com hits your server. The server responds with Access-Control-Allow-Origin: https://app-a.com. The CDN caches this response.
  2. A request for the same resource comes from https://app-b.com. The CDN serves the cached response — which still has Access-Control-Allow-Origin: https://app-a.com.
  3. The browser sees the origin mismatch and blocks it with a CORS error.

Vary: Origin tells the cache that the response differs depending on the Origin header, so it should store and serve separate cached versions for each origin.

When should I NOT try to fix a CORS error?

Some APIs are designed for server-side use only and intentionally don't include CORS headers. These are typically APIs that require a secret key or private token — like the Google Maps Places API, payment processing APIs, or AI service APIs.

The reason they block browser access is security: if you put a secret API key in your frontend JavaScript, anyone can open DevTools, find the key, and use it themselves — racking up charges on your account or accessing your data.

However, this doesn't mean you need to build an entire backend just to call these APIs. A CORS proxy with secrets management can handle both problems at once — bypassing the CORS restriction while keeping your API key hidden from the browser.

For example, with Corsfix's secrets feature, you store your API key on the server and reference it with a variable. Corsfix injects the real key server-side, so it never appears in your frontend code:

fetch("https://proxy.corsfix.com/?https://api.example.com/data", {
  headers: {
    "Authorization": "Bearer {{API_KEY}}"
  }
});

If you'd rather build your own solution, you can create a simple backend endpoint or serverless function (AWS Lambda, Cloudflare Worker) that stores the key and proxies requests to the API on your behalf.

The rule of thumb: never put secret keys in frontend code — but you don't have to give up on calling the API from the client either.

Ready to eliminate CORS errors?

Start fetching data from any API without browser restrictions.

Fix CORS errors nowNo credit card required.