Skip to content

Fix CORS Expose Headers for Custom Response Headers

DodaTech Updated 2026-06-26 2 min read

In this tutorial, you'll learn about Fix CORS Expose Headers for Custom Response Headers. We cover key concepts, practical examples, and best practices.

Your frontend code calls response.headers.get('X-Total-Count') or a similar custom header, but the value is null. The CORS spec only exposes six safe response headers by default. All custom headers require explicit opt-in via Access-Control-Expose-Headers.

Wrong

The server sends a custom header but does not expose it to the client.

Server sends:

X-Total-Count: 247
X-RateLimit-Remaining: 58

Frontend code:

fetch('https://api.example.com/users')
  .then(res => {
    console.log(res.headers.get('X-Total-Count'));
    console.log(res.headers.get('X-RateLimit-Remaining'));
  });
null
null

The custom headers exist on the wire but the browser hides them from JavaScript because Access-Control-Expose-Headers is not set.

Add the Access-Control-Expose-Headers header with the names of the custom headers you want the frontend to read.

const cors = require('cors');
app.use(cors({
  origin: 'https://app.example.com',
  exposedHeaders: ['X-Total-Count', 'X-RateLimit-Remaining', 'X-Request-Id'],
}));

Manual implementation:

app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', 'https://app.example.com');
  res.setHeader('Access-Control-Expose-Headers',
    'X-Total-Count, X-RateLimit-Remaining, X-Request-Id');
  if (req.method === 'OPTIONS') return res.sendStatus(204);
  next();
});

Response headers now include:

Access-Control-Expose-Headers: X-Total-Count, X-RateLimit-Remaining, X-Request-Id
X-Total-Count: 247
X-RateLimit-Remaining: 58

Frontend code now reads:

fetch('https://api.example.com/users')
  .then(res => {
    console.log(res.headers.get('X-Total-Count'));
    console.log(res.headers.get('X-RateLimit-Remaining'));
  });
247
58

Prevention

  • List every custom response header in Access-Control-Expose-Headers that the frontend needs to read.
  • Use the Access-Control-Expose-Headers with a comma-separated list of header names.
  • Remember that Cache-Control, Content-Language, Content-Length, Content-Type, Expires, and Last-Modified are exposed by default.
  • Add pagination headers (X-Total-Count, X-Page, X-Per-Page) to the expose list when building list APIs.
  • Add rate limit headers (X-RateLimit-Remaining, X-RateLimit-Reset) for client-side throttling.
  • Debug missing headers by checking the Network tab in DevTools to confirm the headers reach the browser.

DodaTech Tools

Doda Browser displays both exposed and hidden response headers in its developer tools, with warnings for headers the server sends but does not expose. The browser's network inspector also shows a separate section for non-exposed headers. DodaZIP's API documentation generator automatically reads and documents all exposed headers from the CORS configuration. Durga Antivirus Pro exposes its threat-score headers through CORS for its web dashboard to display real-time risk metrics, including X-Threat-Level, X-Scan-Duration, and X-Malware-Confidence.

FAQ

### Which response headers are exposed by default in CORS?

The six safe headers exposed by default are Cache-Control, Content-Language, Content-Length, Content-Type, Expires, and Last-Modified. Any other header, including custom ones like X-Total-Count or standard ones like Link, must be listed in Access-Control-Expose-Headers.

How do I expose multiple custom headers?

Set Access-Control-Expose-Headers with a comma-separated list: Access-Control-Expose-Headers: X-Total-Count, X-Request-Id, X-RateLimit-Remaining. In the cors npm package, use the exposedHeaders array option.

Why does the browser hide headers that are present in the response?

The CORS spec requires the browser to only expose a subset of response headers to JavaScript unless the server explicitly opts in. This prevents malicious scripts from reading sensitive headers like Set-Cookie or Authorization from cross-origin responses.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro