CORS
security
web development
allowCredentials
allowedOrigins

When allowCredentials is true, allowedOrigins cannot contain the special value

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

This CORS error means your server is trying to allow credentialed cross-origin requests while also using the wildcard origin. Browsers do not permit that combination. If cookies, authorization headers, or other credentials are allowed, the server must name specific origins instead of responding as if any origin were acceptable.

Why * And Credentials Cannot Be Combined

CORS has two relevant ideas here:

  • 'Access-Control-Allow-Origin tells the browser which origin may read the response'
  • 'Access-Control-Allow-Credentials: true tells the browser that cookies or other credentials may be included'

If the server said both "credentials are allowed" and "every origin is allowed," then any website could make authenticated requests on behalf of the user. That is exactly the scenario browsers are trying to prevent.

So when credentials are enabled, Access-Control-Allow-Origin must be a concrete origin such as https://app.example.com, not *.

What A Correct Response Looks Like

For a credentialed request from https://app.example.com, the response should look conceptually like this:

http
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true

The origin is echoed or matched explicitly. It is not a wildcard.

The browser checks this rule on both the main response and, when applicable, the preflight exchange. So even if your application code seems correct, a wrong preflight CORS header can still trigger the same failure in the browser.

A Spring Configuration Example

This error often appears in Spring applications. The fix is to list specific origins instead of *.

java
1import org.springframework.context.annotation.Bean;
2import org.springframework.context.annotation.Configuration;
3import org.springframework.web.servlet.config.annotation.CorsRegistry;
4import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
5
6@Configuration
7public class CorsConfig {
8    @Bean
9    public WebMvcConfigurer corsConfigurer() {
10        return new WebMvcConfigurer() {
11            @Override
12            public void addCorsMappings(CorsRegistry registry) {
13                registry.addMapping("/**")
14                        .allowedOrigins("https://app.example.com")
15                        .allowedMethods("GET", "POST", "PUT", "DELETE")
16                        .allowCredentials(true);
17            }
18        };
19    }
20}

If you truly need a set of dynamic subdomains, newer Spring code often uses origin patterns instead of a literal wildcard in allowedOrigins.

java
1registry.addMapping("/**")
2        .allowedOriginPatterns("https://*.example.com")
3        .allowedMethods("GET", "POST")
4        .allowCredentials(true);

That is different from saying every origin is allowed.

Node And Express Follow The Same Rule

The same CORS rule applies outside Spring. In Express, you should return a specific allowed origin when credentials are enabled.

javascript
1const cors = require('cors');
2const express = require('express');
3
4const app = express();
5
6app.use(cors({
7  origin: 'https://app.example.com',
8  credentials: true,
9}));

Again, the key idea is explicit origin matching.

When You Can Use *

The wildcard is fine only when you are not allowing credentials.

For a fully public API that does not rely on cookies or authenticated browser state, this is acceptable:

http
Access-Control-Allow-Origin: *

But once credentialed browser requests enter the picture, the configuration has to become more specific.

That is why many APIs split their policies into two groups: public unauthenticated endpoints can be more permissive, while authenticated browser endpoints must use a narrow allowed-origin list.

Common Pitfalls

The most common mistake is assuming CORS wildcard behavior and credential support are independent toggles. They are not. The moment you enable credentials, the wildcard origin stops being valid.

Another issue is confusing server-to-server calls with browser-enforced CORS. This rule matters because browsers enforce it on cross-origin frontend requests.

It is also easy to overlook preflight behavior. Even if the main route looks fine, the preflight response must still reflect the correct origin and credential policy.

Finally, avoid broad origin matching unless you genuinely trust every allowed host. Credentialed cross-origin access should be narrow by design.

Summary

  • Credentialed CORS responses cannot use Access-Control-Allow-Origin: *.
  • If allowCredentials is true, the server must allow specific origins.
  • In frameworks such as Spring or Express, configure explicit origins or carefully scoped origin patterns.
  • Use * only for non-credentialed public cross-origin access.
  • Treat this error as a security constraint, not as a framework quirk.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.