# Access-Control-Allow-Origin Header — Values & Examples

> Tells the browser which origin may read this response from JavaScript running on another site.

Browsers block JavaScript from reading responses from another origin unless the server opts in. This header is that opt-in: it names the one origin allowed to read the response, or `*` for any. It must be on the actual response — and, for preflighted requests, on the OPTIONS response too.

The server always receives and processes the request; CORS only controls whether the calling page can see the answer.

- Type: Response header
- Category: CORS
- Defined in: [Fetch Standard — CORS protocol](https://fetch.spec.whatwg.org/#http-cors-protocol)

## Syntax

```http
Access-Control-Allow-Origin: * | <origin> | null
```

## Values

| Value | Meaning |
|---|---|
| `*` | any origin may read it — not allowed together with credentials |
| `https://app.example.com` | exactly this origin (scheme, host and port) |
| `null` | the opaque 'null' origin — avoid, since sandboxed iframes and file:// pages send it |

## Examples

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

one trusted front end

```http
Access-Control-Allow-Origin: *
```

a public API with no cookies or auth headers

## Good to know

- It takes one origin, not a list. To allow several, check the request's `Origin` against an allowlist and echo the match back.
- When the value depends on the request's `Origin`, also send `Vary: Origin` so caches don't serve one site's answer to another.
- `*` doesn't work for requests with cookies or `Authorization`: send the exact origin plus `Access-Control-Allow-Credentials: true`.
- Never echo back any `Origin` without checking it — that switches CORS protection off for every site.

## How to set Access-Control-Allow-Origin

### Express (cors package)

```
import cors from "cors";

app.use(cors({
  origin: ["https://app.example.com", "https://admin.example.com"],
  credentials: true, // only if the browser sends cookies
}));
// Echoes the matching origin, adds Vary: Origin and answers preflights.
```

### Next.js (next.config.js)

```
module.exports = {
  async headers() {
    return [
      {
        source: "/api/:path*",
        headers: [
          { key: "Access-Control-Allow-Origin", value: "https://app.example.com" },
          { key: "Access-Control-Allow-Methods", value: "GET, POST, PUT, DELETE" },
          { key: "Access-Control-Allow-Headers", value: "Content-Type, Authorization" },
        ],
      },
    ];
  },
};
```

### nginx (allowlist)

```
map $http_origin $cors_origin {
  default "";
  "https://app.example.com" $http_origin;
}

server {
  location /api/ {
    add_header Access-Control-Allow-Origin $cors_origin always;
    add_header Vary Origin always;
    # ...
  }
}
```

## Check it

Fetch only the response headers and filter for Access-Control-Allow-Origin. In the browser, it's under Response Headers in DevTools → Network.

```sh
curl -sI https://example.com/ | grep -i '^access-control-allow-origin:'
```

## FAQ

### Can I list multiple origins in Access-Control-Allow-Origin?

No. The header accepts a single origin or *. Compare the request's Origin header to your allowlist and return the one that matched, with Vary: Origin.

### Why does the request reach my server but the browser still reports a CORS error?

CORS is enforced by the browser when it reads the response. The server ran the request; the browser hid the result because this header was missing or didn't match.

## Related headers

- [Origin](https://www.devkult.com/headers/origin.md): Sent by browsers to say which origin — scheme, host and port — a request comes from.
- [Access-Control-Allow-Credentials](https://www.devkult.com/headers/access-control-allow-credentials.md): Allows a cross-origin page to read a response to a request made with cookies or HTTP authentication.
- [Access-Control-Allow-Methods](https://www.devkult.com/headers/access-control-allow-methods.md): Lists the HTTP methods a cross-origin request may use, in the response to a CORS preflight.
- [Access-Control-Allow-Headers](https://www.devkult.com/headers/access-control-allow-headers.md): Lists the request headers a cross-origin request may include, in the response to a CORS preflight.
- [Vary](https://www.devkult.com/headers/vary.md): Lists the request headers that change the response, so caches keep a separate copy for each variant.

## Further reading

- [CORS errors explained](https://www.devkult.com/blog/cors-errors-explained.md)

Open the interactive page: https://www.devkult.com/headers/access-control-allow-origin