Diagnosing Empty DataTables with Server-Side Processing
DataTables returns HTTP 200 with JSON but shows zero rows; verify draw, totals, data array, and column mappings.
26 Aug 2026, 11:57 UTC

The problem and what to check first
You initialize a DataTable with serverSide: true. The browser network panel shows HTTP 200 and a JSON payload, but the table displays "No data available in table" with zero rows. The request reached the server and the server replied, yet DataTables never renders the records.
Useful takeaway: an HTTP 200 response only means the server answered. DataTables also requires specific JSON keys, matching column mappings, and a valid draw echo before it will render server-side data.
Recognizable condition
Symptoms: a table initialized with Ajax and serverSide: true, network request returns HTTP 200 with JSON, but DataTables shows zero rows or the "No data available in table" message. No visible change after the Ajax request completes.
Cause and diagnostic table
| Observation | Likely cause |
|---|---|
Response missing draw, recordsTotal, recordsFiltered, or data | Server payload does not follow the DataTables server-side protocol |
draw value does not match the request | DataTables ignores the response as stale |
recordsTotal or recordsFiltered is a string or missing | DataTables cannot calculate pagination or display records |
data is not an array | DataTables has no rows to iterate |
columns.data or columnDefs.targets do not match JSON keys | Rows exist but cells render empty |
| JavaScript exception in console during draw | Client-side error stops rendering before rows appear |
Ordered checks
- Confirm HTTP 200 and valid JSON. Open DevTools, go to Network, filter XHR/fetch, reload the page, and select the DataTables request. Verify the Response tab contains parseable JSON, not an HTML error page.
- Verify the
drawecho. Compare thedrawvalue sent in the request with thedrawvalue in the response.drawis an integer DataTables uses to match responses to outstanding requests; mismatched values are discarded. - Verify total counts are integers. Check that
recordsTotalandrecordsFilteredare present and numeric. String values or nulls can prevent rendering. - Verify
datais an array. The response must includedataas an array, even when empty. An object or missing key yields zero rows. - Match column mappings to JSON keys. Compare each
columns.datavalue orcolumnDefstarget against the property names inside thedataobjects. - Check the console. Look for DataTables warnings or uncaught JavaScript exceptions that occur while the table is drawing.
- Isolate with a static Ajax object. Replace the server URL with a hardcoded JavaScript object containing the expected JSON structure. If the table renders, the problem is server-side; if it still fails, the problem is client configuration.
Fixes tied to findings
- Echo
draw. Return the exactdrawinteger received from the client, typicallyparseInt(request.draw, 10). - Cast counts to integers. Return
recordsTotalandrecordsFilteredas numbers, not strings. - Ensure
datais an array. Return"data": []when no records match, notnullor an object. - Use
ajax.dataSrcif wrapped. If the server nests results under a property such asresults, setajax: { url: "/api/users", dataSrc: "results" }. - Correct
columns.datamappings. Setcolumns: [{ data: "id" }, { data: "name" }]to match JSON keys exactly. - Clear and redraw after changes. After changing Ajax or column configuration, call
table.clear().draw()or re-initialize the table instance.
Concrete example configuration
This example assumes DataTables 1.10 or 2.x and a server response shaped like:
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [
{ "id": 1, "name": "Ada Lovelace", "role": "Engineer" },
{ "id": 2, "name": "Grace Hopper", "role": "Engineer" }
]
}
Matching client initialization:
var table = $('#example').DataTable({
serverSide: true,
ajax: {
url: '/api/users',
type: 'GET'
},
columns: [
{ data: 'id' },
{ data: 'name' },
{ data: 'role' }
]
});
If the server instead wraps rows under users, add dataSrc:
ajax: {
url: '/api/users',
dataSrc: 'users'}
Version assumptions
DataTables 1.10 and 2.x differ in initialization syntax, option names, and event names. Confirm the installed version before applying version-specific fixes. The examples above use the common serverSide, ajax, and columns.data options present in both major lines, but check your release notes if you recently upgraded.
Limitations
This guide covers Ajax server-side processing only. It does not apply to DOM-sourced tables, client-side processing, or tables that mix Ajax and inline data on the same instance. It also does not cover authentication failures, CORS errors, or slow queries that time out before DataTables receives a response.
Practical verification
After applying a fix, reload the page and inspect the Network response again. Confirm data contains objects and that the table body shows the expected rows. Open the console and run table.settings()[0] to inspect the active DataTables settings and compare them against your column configuration.
Escalation criteria
Escalate to the DataTables issue tracker or a senior engineer when all of the following are true:
- The network response is valid JSON with
draw,recordsTotal,recordsFiltered, anddata. - Client column mappings match the JSON keys.
- No console errors appear during initialization or draw.
- A static Ajax object renders correctly but the production API does not.
Capture the DataTables version, browser, minimal HTML, and the full JSON response before escalating. Treat failures that begin after a library upgrade as potential breaking changes in Ajax or rendering behavior.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.