AI-Ready Data Hyungyu Lee

Nothing Found Is Not Nothing There: How to Test an Empty Result

Four lavender tiles stepping upward behind a frosted window, with one deep purple tile outside it

Silent data loss is data that a read, load or query drops without returning any error, so that an empty or incomplete result looks the same as a true absence.

In August 2023, United States federal agencies were due to reach the advanced tier of event logging. Auditors counted three of 23 agencies at that tier and 17 at tier 0, the level where the highest-criticality logging requirements are not met or only partially met.

Any of those 17 could truthfully report that no intrusion was detected. For them, the sentence described their logging, not their networks.

That gap between “there is nothing there” and “nothing came back” shows up in every data team, and the lesson is narrower than distrusting data in general: every look at data passes through a tool, a query or a default, and some of those have no way to report what they left out.

Every read is a window

Nobody reads a whole dataset. People read a query, a preview, a sample or a default, and that read stands in for the thing they meant.

Schema inference is a plain example. When a file loads into BigQuery without a declared schema, the service scans up to the first 500 rows of a randomly selected file to decide column types.

The choice is reasonable and documented. It also means a column with forty million rows gets its type from five hundred, and values past row five hundred that contradict the type become rejected rows, nulls or quiet coercions.

Capacity is another. Between 25 September and 2 October 2020, England’s public health agency left 15,841 positive test results out of its daily figures because some files exceeded the maximum file size. No error stopped the load. It kept running with less in it.

The author has his own smaller cases. A pull of a project’s work items through an interface that followed only direct children missed 73 items, 41 percent of the total, and the result still looked complete.

A tool’s help summary listed 44 subcommands when the tool had 88. In both cases the partial read looked clean, which is what made it convincing.

Three shapes of silent data loss

Tools do warn sometimes. A spreadsheet tells a person it is truncating a file. A technical analysis of the England case argues the row limit should not have stopped a well-designed import.

That is the point: the warning was written for a person, and in the path that ran, there was no person. Loud failures such as alert floods are a separate problem with separate remedies.

Three shapes of silent data loss
ShapeWhat happensExample
Warning with no recipientThe message exists, but a script receives itAn import tool that warns about truncation inside an unattended pipeline
Record with no field for the eventThe log contains everything it can contain, and the event is not one of those thingsLogging configured below the level that would capture the activity
Query that returns nothing and no errorValid syntax, correct engine, empty resultIn MariaDB, if a subquery yields any NULL, NOT IN never evaluates to TRUE

In all three, the output cannot carry the loss. The notice is not waiting in a queue for a more careful reader. More attention will not find it, because no record of the loss exists anywhere a reader can go.

Why an empty result is the hardest output to check

A wrong number has neighbors. It sits beside other numbers, and comparing them can expose it. An empty result has nothing beside it. The only thing to check it against is an expectation, and the read was supposed to supply that expectation. So it passes.

For about ten months, an inspection tool on Equifax’s network inspected nothing because a certificate had expired. Auditors found the attacker could run commands and remove stolen data without detection.

When the certificate was replaced, signs of the intrusion appeared the same day. For ten months, a quiet console meant the tool had stopped reporting, not that the network was quiet.

The same pattern appeared in a 2023 cloud email intrusion. The Cyber Safety Review Board recorded that the State Department found it because it had purchased enhanced logging that few other victims had. Victims that enabled logging afterward could not see earlier activity. The intrusion was equally real everywhere. What differed was whether anything had been recording.

Sensitivity of a read. How likely a read was to surface something, assuming there was something to find. An absence counts as evidence roughly in proportion to that likelihood. It is a property of the instrument, and it is rarely measured.

How to test whether a zero is real

Looking harder will not close the gap. A better move is to make the instrument return something already known to be true and see whether it can.

  • Send a known positive down the same path. Security teams already do this with open libraries such as Atomic Red Team, which fire a known technique on purpose to check whether detections detect. The same idea works for a query or a pipeline.
  • Count the denominator twice. Row-count reconciliation is a standard test in tools such as dbt-expectations. It usually runs on unattended pipelines, not on the exploratory query someone runs an hour before a meeting and then quotes in a decision.
  • Write “nothing came back” and “there is nothing” as different sentences. A reader who receives the flattened version cannot unflatten it.

None of these catches the first case. A type inferred from five hundred rows leaves no missing row to count and no detector that failed to fire.

The wrong decision is already inside the data by the time the contradicting values arrive. The honest response is to record which reads made which decisions, so a later reviewer knows where to look.

Before a team treats an empty or small result as a fact, it can ask:

  • What would this read have shown if the thing existed?
  • Has the same path ever returned a known positive?
  • Do row counts match between the source and what the read returned?
  • Were any types, filters or limits decided from a sample?
  • Does the report separate “no result” from “confirmed absent”?

Why this matters for AI-ready data

AI systems inherit these gaps. A training or evaluation set built from a truncated load, a sampled schema or a silent filter carries its missing rows into every model result, and the model has no way to report what it never saw.

That is one reason clean-looking data is not the same as AI-ready data. It also explains why a result that cannot be reproduced from a recorded data state is hard to investigate when it moves.

When a dataset is checked for integrity, the useful question is not only “is it complete?” but also “how would we know if it were not?” Real empty values and important exceptions should stay visible rather than being filled in to make the data look tidy.

Check whether a dataset is missing, duplicated or silently coerced before an AI task depends on it, and keep the version you checked. See how Syntitan diagnoses data state across integrity, context and traceability.

Syntitan, the AI-ready data platform. Try it on your data, free.

FAQ

What is silent data loss?

It is data dropped by a read, load or query without an error, so an incomplete or empty result looks the same as a true absence.

Is absence of evidence ever evidence of absence?

Yes, roughly in proportion to how likely the read was to find something if it existed. That likelihood belongs to the instrument and is rarely measured.

How can a team test an empty query result?

Send a known positive through the same path, reconcile row counts against the source, and check whether types or filters were decided from a sample.

Why does silent data loss matter for AI?

Missing rows in training or evaluation data shape every model result, and the model cannot report what it never saw.