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

  1. Make the API send X-Total-Count on list endpoints (e.g. res.set('X-Total-Count', total) in Express).
  2. If using CORS, add it to Access-Control-Expose-Headers: 'X-Total-Count' on the server.
  3. Verify with curl -I that the header is actually present in the raw response.
  4. 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

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


AI-assisted analysis of marmelab/react-admin@051f511bb0 (2026-08-30). Data as JSON: /api/errors/929ffd71c13812fe. Report an issue: GitHub.