marmelab/react-admin · error
The X-Total-Count header is missing in the HTTP Response. Th
Error message
The X-Total-Count header is missing in the HTTP Response. The jsonServer Data Provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?
What it means
The jsonServer data provider reads the total record count for paginated lists from the X-Total-Count response header. If the header is absent on a list response, pagination cannot be computed and the provider throws with guidance about CORS exposure.
Source
Thrown at packages/ra-data-json-server/src/index.ts:58
const { field, order } = params.sort || {};
const query = {
...fetchUtils.flattenObject(params.filter),
_sort: field,
_order: order,
_start:
page != null && perPage != null
? (page - 1) * perPage
: undefined,
_end: page != null && perPage != null ? page * perPage : undefined,
_embed: params?.meta?.embed,
};
const url = `${apiUrl}/${resource}?${stringify(query)}`;
const { headers, json } = await httpClient(url, {
signal: params?.signal,
});
if (!headers.has('x-total-count')) {
throw new Error(
'The X-Total-Count header is missing in the HTTP Response. The jsonServer Data Provider expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?'
);
}
const totalString = headers.get('x-total-count')!.split('/').pop();
if (totalString == null) {
throw new Error(
'The X-Total-Count header is invalid in the HTTP Response.'
);
}
return { data: json, total: parseInt(totalString, 10) };
},
getOne: async (resource, params) => {
let url = `${apiUrl}/${resource}/${params.id}`;
if (params?.meta?.embed) {
url += `?_embed=${params.meta.embed}`;
}
const { json } = await httpClient(url, { signal: params?.signal });View on GitHub (pinned to 051f511bb0)
Solutions
- Make the API send X-Total-Count on list endpoints (e.g. res.set('X-Total-Count', total) in Express).
- If using CORS, add it to Access-Control-Expose-Headers: 'X-Total-Count' on the server.
- Verify with curl -I that the header is actually present in the raw response.
- Test outside the browser to distinguish missing header from CORS filtering.
Example fix
// before (Express + CORS)
app.use(cors()); // header hidden from browser
// after
app.use(cors({ exposedHeaders: ['X-Total-Count'] }));
res.set('X-Total-Count', total); Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(`${apiUrl}/${resource}?range=0-9`);
if (!res.headers.has('x-total-count')) {
throw new Error('Backend does not expose X-Total-Count on list endpoints');
} Type guard
const hasTotalCount = (headers: Headers): boolean => headers.has('x-total-count'); Try / catch
try {
const { data, total } = await dataProvider.getList(resource, params);
return { data, total };
} catch (e) {
if (e.message.includes('X-Total-Count')) {
console.error('List response missing X-Total-Count; check API and CORS expose-headers', e);
}
throw e;
} Prevention
- Configure the API (or json-server middleware) to always send X-Total-Count on collections.
- Add 'X-Total-Count' to Access-Control-Expose-Headers in your CORS setup.
- Verify headers with curl before debugging in the browser, to rule out CORS filtering.
- Add an integration test asserting the header on list endpoints.
When it happens
Trigger: Any getList call whose HTTP response lacks the x-total-count header — typically because the API doesn't send it, or because CORS filters it out unless listed in Access-Control-Expose-Headers.
Common situations: Pointing the provider at a non-json-server API that doesn't emit the header; CORS-blocking the header in browsers while present in curl; custom middleware stripping headers; using json-server without the count header on custom routes.
Related errors
- The ${countHeader} header is missing in the HTTP Response. T
- The X-Total-Count header is invalid in the HTTP Response.
- Found getManyReference result in cache without total or page
- ra.navigation.page_out_of_boundaries
- The Pagination limit prop is deprecated. Empty state should
AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30).
Data as JSON: /api/errors/929ffd71c13812fe.
Report an issue: GitHub.