Skip to main content

How to Resolve the "CORS Error: Access-Control-Allow-Origin cannot be * when credentials mode is 'include'" Error in JavaScript

The error The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include' is a specific CORS (Cross-Origin Resource Sharing) error. It is a security measure enforced by browsers to prevent sensitive user information from being shared with untrusted origins.

This guide will explain the fundamental security principle that causes this error and show you how to fix it by correctly configuring the CORS headers on your server.

The Core Problem: The Conflict Between "Everyone" and "Credentials"

This error arises from the interaction of two different settings: one on the client (your frontend app) and one on the server (your backend API).

  • On the Client (Frontend): Your code is making a request with credentials: 'include'. This happens when you use fetch with that option, or when you set withCredentials: true in Axios. It tells the browser, "Please include any cookies, authorization headers, or client certificates that are relevant for the destination domain in this cross-origin request."

  • On the Server (Backend): Your server is responding with the header Access-Control-Allow-Origin: *. The wildcard (*) means "I allow any domain on the internet to make requests to me."

The browser sees this combination and stops the request for security reasons. The logic is: "A request that includes private user credentials cannot be sent to a server that allows anybody to access it. This is too insecure."

You cannot simultaneously allow "everyone" (*) and also handle "private credentials." You must choose one.

The Solution: Specify the Exact Origin

Since your goal is to send credentials, you cannot use the wildcard. The solution is to change your server's configuration to specify the exact origin(s) that are allowed to make credentialed requests.

Example of problem (Incorrect Server Configuration):

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

The Solution is a Correct Server Configuration: you must replace the wildcard (*) with the full, specific origin of your frontend application.

# The origin must include the protocol, domain, and port.
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Credentials: true

This tells the browser: "I explicitly trust http://localhost:3000. It is safe to send credentials from that specific origin."

A Practical Example (Node.js/Express)

Most backend frameworks have libraries to manage CORS. For a Node.js server using Express, the cors middleware is the standard solution.

Problem: your Express API is configured with a wildcard origin but you need to handle cookies from your frontend.

// Problematic configuration
app.use(cors({ origin: '*', credentials: true })); // This will not work

Solution: specify the trusted origin directly.

let express = require('express');
let cors = require('cors');
let app = express();

let corsOptions = {
// Replace with your frontend's actual origin
origin: 'http://localhost:3000',
credentials: true, // Allow cookies to be sent
};

// Enable CORS with the specific options
app.use(cors(corsOptions));

// Your API routes...
app.get('/api/me', (req, res) => {
// This route can now access cookies sent from the frontend
res.json({ user: 'authenticated' });
});

app.listen(8000);

How to Handle Multiple Origins

If you need to allow credentialed requests from multiple specific origins (e.g., your local development environment and your production domain), you can provide a function or an array to your CORS configuration.

Example of solution using Express cors middleware:

let whitelist = ['http://localhost:3000', 'https://my-production-app.example.com'];

let corsOptions = {
origin: function (origin, callback) {
// The `origin` is the domain that made the request.
// Check if the origin is in our whitelist.
if (whitelist.indexOf(origin) !== -1 || !origin) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
credentials: true,
};

app.use(cors(corsOptions));
note

This configuration dynamically checks if the incoming request's origin is on your list of trusted domains and responds with the appropriate CORS headers.

Conclusion

The error The value of the 'Access-Control-Allow-Origin' header ... must not be the wildcard '*' is a security feature, not a bug. It forces you to be explicit about which domains you trust with user credentials.

To solve it, you must modify your server-side CORS configuration:

  • Change Access-Control-Allow-Origin from * to a specific, trusted origin (e.g., https://my-frontend.com).
  • Ensure Access-Control-Allow-Credentials is set to true.

This creates a secure channel that allows your frontend and backend to exchange credentials across different domains.