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

  1. Fix the server/proxy to always send a non-empty numeric X-Total-Count value (e.g. 'X-Total-Count: 42').
  2. Check middleware/CORS configuration for anything stripping or blanking the header value.
  3. Verify with browser devtools that the header value is present and numeric, optionally with a 'range/total' format like '0-9/42'.
  4. 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

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


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