marmelab/react-admin · error
The ${countHeader} header is missing in the HTTP Response. T
Error message
The ${countHeader} header is missing in the HTTP Response. The simple REST 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 ${countHeader} in the Access-Control-Expose-Headers header? What it means
The simple REST data provider's getList reads the total count of records from a response header (Content-Range by default, configurable via httpLink/countHeader). If the response lacks that header, pagination cannot be built, so it throws. This is almost always a server or CORS configuration issue, not a client bug.
Source
Thrown at packages/ra-data-simple-rest/src/index.ts:75
};
if (params.meta && params.meta.embed) {
query.embed = JSON.stringify(params.meta.embed);
}
const url = `${apiUrl}/${resource}?${stringify(query)}`;
const options =
countHeader === 'Content-Range'
? {
// Chrome doesn't return `Content-Range` header if no `Range` is provided in the request.
headers: new Headers({
Range: `${resource}=${rangeStart}-${rangeEnd}`,
}),
signal: params?.signal,
}
: { signal: params?.signal };
return httpClient(url, options).then(({ headers, json }) => {
if (!headers.has(countHeader)) {
throw new Error(
`The ${countHeader} header is missing in the HTTP Response. The simple REST 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 ${countHeader} in the Access-Control-Expose-Headers header?`
);
}
return {
data: json,
total:
countHeader === 'Content-Range'
? parseInt(
headers.get('content-range')!.split('/').pop() ||
'',
10
)
: parseInt(headers.get(countHeader.toLowerCase())!),
};
});
},
getOne: async (resource, params) => {View on GitHub (pinned to 051f511bb0)
Solutions
- Make the server send the count header (e.g. Content-Range: posts 0-9/42) on list endpoints
- If the API is cross-origin, add the header to Access-Control-Expose-Headers in the server's CORS config
- If your API uses a different header name, configure it: simpleRestProvider(url, httpClient, 'X-Total-Count')
Example fix
// before (Express)
res.set('Content-Range', `posts ${start}-${end}/${total}`);
// after (also expose for CORS)
res.set('Content-Range', `posts ${start}-${end}/${total}`);
res.set('Access-Control-Expose-Headers', 'Content-Range'); Defensive patterns
Strategy: validation
Validate before calling
// Probe the endpoint before wiring the provider
const res = await fetch(`${apiUrl}/posts?range=${encodeURIComponent('[0,9]')}`);
if (!res.headers.has('Content-Range')) {
console.warn('Server does not send Content-Range; configure countHeader or fix server/CORS');
} Type guard
const hasCountHeader = (headers: Headers, name = 'Content-Range'): boolean =>
headers.has(name); Try / catch
try {
const data = await dataProvider.getList('posts', { pagination: { page: 1, perPage: 10 } });
} catch (e) {
if (e instanceof Error && e.message.includes('header is missing')) {
notify('Server does not expose the total count header; fix server/CORS config', { type: 'error' });
return { data: [], total: 0 };
}
throw e;
} Prevention
- Verify list endpoints send Content-Range (or your custom countHeader) with curl -i
- Always add the count header to Access-Control-Expose-Headers in CORS middleware
- Match the third argument of simpleRestProvider to the header your API actually sends
- Add an integration test asserting list responses include the count header
When it happens
Trigger: Calling dataProvider.getList() when the backend response for the collection endpoint does not include the count header (e.g. missing Content-Range), or the header is present server-side but stripped by the browser because it was not listed in Access-Control-Expose-Headers.
Common situations: Cross-origin APIs where the server sends Content-Range but does not expose it via CORS; backends (e.g. Express, Rails, API Platform misconfigured) that never send Content-Range for list endpoints; using a custom countHeader name (via httpLink customHeaderName option) that the server does not actually send.
Related errors
- The X-Total-Count header is missing in the HTTP Response. Th
- 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/9bc5468fb63fc686.
Report an issue: GitHub.