marmelab/react-admin · error
The X-Total-Count header is invalid in the HTTP Response.
Error message
The X-Total-Count header is invalid in the HTTP Response.
What it means
The ra-data-json-server data provider parses the total number of records from the X-Total-Count response header required by JSON Server style APIs. It reads the header, splits on '/', and throws this error if the resulting value is null — i.e. the header exists but has no parseable content. This indicates a malformed header value rather than a missing header.
Source
Thrown at packages/ra-data-json-server/src/index.ts:64
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 });
return { data: json };
},
getMany: async (resource, params) => {
const query = {
id: params.ids,View on GitHub (pinned to 051f511bb0)
Solutions
- Fix the server/proxy to always send a non-empty numeric X-Total-Count value (e.g. 'X-Total-Count: 42').
- Check middleware/CORS configuration for anything stripping or blanking the header value.
- Verify with browser devtools that the header value is present and numeric, optionally with a 'range/total' format like '0-9/42'.
- Upgrade the data provider package in case a newer version handles this case differently.
Example fix
// before (server: Express)
res.set('X-Total-Count', '');
// after
res.set('X-Total-Count', String(total)); Defensive patterns
Strategy: validation
Validate before calling
const res = await fetch(url);
const raw = res.headers.get('x-total-count');
if (raw == null || raw === '') {
throw new Error(`Invalid X-Total-Count header: '${raw}'`);
}
const total = parseInt(raw.split('/').pop() ?? '', 10);
if (Number.isNaN(total)) throw new Error(`Non-numeric X-Total-Count: '${raw}'`); Type guard
function hasValidTotalCount(headers: Headers): headers is Headers & { get(h: 'x-total-count'): string } {
const v = headers.get('x-total-count');
return v != null && v.split('/').pop() != null && !Number.isNaN(parseInt(v.split('/').pop()!, 10));
} Try / catch
try {
const { data, total } = await dataProvider.getList(resource, params);
} catch (e) {
if (e.message.includes('X-Total-Count header is invalid')) {
notify('Server sent a malformed pagination header', { type: 'warning' });
} else throw e;
} Prevention
- Verify X-Total-Count in devtools/network tab for every list endpoint.
- Include the header in CORS Access-Control-Expose-Headers.
- Add an integration test asserting the header on list responses.
- Add contract tests for any proxy/middleware so it never blanks the header.
When it happens
Trigger: Calling getList (or getManyReference) on a JSON Server API whose response contains an X-Total-Count header that is empty or whose value, after splitting on '/', yields null (e.g. an empty header value).
Common situations: Server or proxy sends X-Total-Count with an empty value; custom middleware strips the header value while keeping the key; misconfigured server writes the header without a value.
Related errors
- The X-Total-Count header is missing in the HTTP Response. Th
- The ${countHeader} header is missing in the HTTP Response. T
- 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/caec791cae7410e6.
Report an issue: GitHub.