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 usefetchwith that option, or when you setwithCredentials: truein 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));
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-Originfrom*to a specific, trusted origin (e.g.,https://my-frontend.com). - Ensure
Access-Control-Allow-Credentialsis set totrue.
This creates a secure channel that allows your frontend and backend to exchange credentials across different domains.