{"record":{"id":"caec791cae7410e6","repo":"marmelab/react-admin","slug":"the-x-total-count-header-is-invalid-in-the-http-re","errorCode":null,"errorMessage":"The X-Total-Count header is invalid in the HTTP Response.","messagePattern":"The X-Total-Count header is invalid in the HTTP Response\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/ra-data-json-server/src/index.ts","lineNumber":64,"sourceCode":"                page != null && perPage != null\n                    ? (page - 1) * perPage\n                    : undefined,\n            _end: page != null && perPage != null ? page * perPage : undefined,\n            _embed: params?.meta?.embed,\n        };\n        const url = `${apiUrl}/${resource}?${stringify(query)}`;\n\n        const { headers, json } = await httpClient(url, {\n            signal: params?.signal,\n        });\n        if (!headers.has('x-total-count')) {\n            throw new Error(\n                '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?'\n            );\n        }\n        const totalString = headers.get('x-total-count')!.split('/').pop();\n        if (totalString == null) {\n            throw new Error(\n                'The X-Total-Count header is invalid in the HTTP Response.'\n            );\n        }\n        return { data: json, total: parseInt(totalString, 10) };\n    },\n\n    getOne: async (resource, params) => {\n        let url = `${apiUrl}/${resource}/${params.id}`;\n        if (params?.meta?.embed) {\n            url += `?_embed=${params.meta.embed}`;\n        }\n        const { json } = await httpClient(url, { signal: params?.signal });\n        return { data: json };\n    },\n\n    getMany: async (resource, params) => {\n        const query = {\n            id: params.ids,","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/marmelab/react-admin/blob/051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0/packages/ra-data-json-server/src/index.ts#L46-L82","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before (server: Express)\nres.set('X-Total-Count', '');\n// after\nres.set('X-Total-Count', String(total));","handlingStrategy":"validation","validationCode":"const res = await fetch(url);\nconst raw = res.headers.get('x-total-count');\nif (raw == null || raw === '') {\n    throw new Error(`Invalid X-Total-Count header: '${raw}'`);\n}\nconst total = parseInt(raw.split('/').pop() ?? '', 10);\nif (Number.isNaN(total)) throw new Error(`Non-numeric X-Total-Count: '${raw}'`);","typeGuard":"function hasValidTotalCount(headers: Headers): headers is Headers & { get(h: 'x-total-count'): string } {\n    const v = headers.get('x-total-count');\n    return v != null && v.split('/').pop() != null && !Number.isNaN(parseInt(v.split('/').pop()!, 10));\n}","tryCatchPattern":"try {\n    const { data, total } = await dataProvider.getList(resource, params);\n} catch (e) {\n    if (e.message.includes('X-Total-Count header is invalid')) {\n        notify('Server sent a malformed pagination header', { type: 'warning' });\n    } else throw e;\n}","preventionTips":["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."],"tags":["http","pagination","json-server","header"],"backgroundTag":"missing-x-total-count-header","analyzedSha":"051f511bb0afb5ea565c2d3728bf4dab0a6fa5e0","analyzedAt":"2026-08-30T02:28:14.926Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}