Lab Technical Report LAB-TR-0037

Silent Parser Failures Hide Findings and Invent Deletions Under Stated Decision Rules: A Fault-Injection Study on Synthetic Phones

Lab Technical Report, preprint, not peer reviewed

Abstract

A parser that fails silently hands an examiner an ordinary-looking table, and how far that changes a conclusion has not been measured. We inject six classes of silent failure (empty or truncated reads, dropped rows, wrong columns, time shifts, duplicated rows; 15 conditions) into the output of a parser for 300 synthetic phones from a calibrated generator and apply ten stated decision rules that stand in for examiner conclusions, such as “app installed on day D”. The examiner is simulated. Rules about what exists can only lose findings: row loss hid 3% of the YES answers when 5% of the rows were dropped and all of them when the read was empty. Counter rules compare an intact counter with the rows read, so the same loss made them report removals in all 100 message and call stores (94 phones) that had said none. For dropped rows the hidden share follows q to the power of the supporting rows, so days with few records are exposed. A count check sees every loss and duplication flip; four cheap checks saw 11% of the flips caused by time shifts and near wrong columns. Two classes resemble failures measured earlier on real images.

CCS Concepts • Applied computing → System forensics; • Software and its engineering → Software testing and debugging; • General and reference → Evaluation.

Keywords silent failure, mobile forensics, parser validation, fault injection, synthetic data, decision impact, identifier counters

ACM Reference FormatDaniel Addai, Selorm Adjabeng, Kingsley Albert Egyir, and Sanders Larweh Tetteh. 2026. Silent Parser Failures Hide Findings and Invent Deletions Under Stated Decision Rules: A Fault-Injection Study on Synthetic Phones. Lab Technical Report LAB-TR-0037, version 1.0. SectraTEK Lab, Prudential Associates. Preprint, not peer reviewed. https://lab.sectratek.com/research/reports/lab-tr-0037/

1 Introduction

A parser that cannot read a table does not always say so. It may return an empty table, a part of the rows, or rows with a wrong time, and the report looks like any other. The Lab found this on real images: one parser returned none of the image rows of a media database, and another returned only a second Android user’s rows of an app-update database; in both cases the report looked like that of a phone with less data [16]. What is not known is how far such a failure moves the conclusion a reader would draw from the table. A tool that fails rarely matters little if the failures leave the answers untouched, and matters a great deal if they reverse them.

A motivating example. Take one synthetic phone, 653 days old, with 1,115 messages present and a message identifier counter at 1,115: nothing has been removed. Two questions are put to a parser’s output. Was the package app.syn.s001 first installed on 2025-02-13? From the clean output the answer is YES. If a quarter of the package rows are lost, 62 of 85 rows arrive and the answer is NO. Have records been removed from the message store? From the clean output the answer is NO. If the message read returns nothing, the counter still stands at 1,115 and the rule reports 1,115 removed records. The same kind of failure hides a finding in one question and invents one in the other.

The problem. We need to know, for stated failure classes and stated conclusions, how often the conclusion changes, in which direction, and whether a cheap check on the parser’s output would have shown it. Real examiners reason with more than one table, so we do not measure what examiners do. We measure the sensitivity of stated rules to stated failures. We ask four questions.

  • RQ1 (How often). How often does each failure class, at each severity, change the answer of each rule?
  • RQ2 (Which direction). Do failures hide findings, invent them, or both?
  • RQ3 (Cheap checks). How many of the flips would a count, range, uniqueness or order check on the parser’s output expose?
  • RQ4 (Resemblance). Do the injected failures resemble the silent failures measured on real images in LAB-TR-0006?

Table 1 gives the answers.

Table 1: Research questions, answers and evidence. All values are for 300 synthetic phones and the conditions of Table 2.
QuestionAnswerEvidence
RQ1 How oftenRow loss hides 3% to 100% of the YES answers of the existence rules, depending on severity (5% of rows dropped: 2.9%; empty read: 100%); a 6-hour time shift 10.5%; a 1-hour shift 1.8%. Duplicated rows hide none. The loss rate follows 0.25 to the power of the supporting rows for a quarter of rows dropped.Sections 4.2, 4.3; Table 4; Figures 2, 3
RQ2 Which directionRow loss never turned a NO into a YES for an existence rule (0 of 151,632 clean-NO answers; the rules are monotone, so this tests the code), but made the counter rules report removals for all 100 message and call stores that had said none (rows dropped, any rate; 900 of 900 answers from 100 pairs). Duplicated rows hid removals in 17% to 58% of the answers. Time faults move answers both ways.Section 4.2; Table 4
RQ3 Cheap checksA count check sees every flip caused by loss or duplication, by construction. Of the flips caused by a time shift or a near wrong column, the four checks see 11%; a gross wrong column is seen by the range check (93%). The range check also fires on 6% of clean reads.Section 4.4; Table 6; Figure 4
RQ4 ResemblanceTwo of the six classes have a measured counterpart in LAB-TR-0006 (an empty read; dropped rows, as the loss of one user’s rows). Truncation was measured only as an empty read; a wrong column, a time shift and duplicated rows have only a described condition or none. The measured loss fractions (56.8% to 61.8%) lie in the range of a 60% drop, which was chosen to match them: the check is of size, not mechanism.Section 4.5; Table 7

Contributions. This report makes four contributions.

  • A way to measure decision impact: a parse interface with six reads, six failure classes in 15 conditions, ten stated decision rules, and a flip measure with a direction (Sections 3.1 to 3.4).
  • Measured flip shares by class, severity and rule on 300 synthetic phones, with the direction of the change and a closed form for the loss classes (Sections 4.2 and 4.3).
  • The share of flips that four cheap checks expose, by class, with the false alarms of the checks on clean reads (Section 4.4).
  • A table of which injected classes resemble failures measured on real images, and the package: code, results and the generator it uses (Section 4.5 and Artifact Availability).

Scope. The phones are synthetic, made by the generator of LAB-TR-0033 [20]. The failures are injected into the output of a parser, not produced by a parser. The examiner is a set of 10 stated rules, not a person. A flip is a change of a rule’s answer from the answer on the clean read; it is not an error rate of any tool. Section 6 states the limits.

2 Background and Related Work

2.1 Silent failure and schema drift in parsers

Open-source suites of artifact parsers read the databases of phones and apps [2]. The Lab’s own sweep of two such suites on current images found parsers that returned empty tables for stores that held rows, and one that returned only one Android user’s copy of a database [16]. Azahari and colleagues followed 20 Android apps through 320 versions and showed that even small schema changes can invalidate extraction queries or miss new artifacts [1]. Claij-Swart and colleagues generate reference data whenever an app updates, so that tools can be re-tested [5]. Bulla injects five drift conditions into synthetic WhatsApp databases and runs two artifacts of one open-source parser: three conditions produced incomplete extraction (45 false-negative artifacts), one produced five timestamp errors, and none of the four materially wrong runs showed the examiner a diagnostic, whereas a guard that checked the parser’s assumptions flagged all four [3]. That preprint states that it did not test whether warnings change investigative decisions.

2.2 Errors in forensic tools and their treatment

The Scientific Working Group on Digital Evidence separates incompleteness from inaccuracy and warns that the errors of an implementation are systematic and not statistical, so that characterising them by a rate is often misleading [13]. Hargreaves, Nelson and Casey model a tool as stages and ask where errors enter and how they spread [6]. Horsman maps sources of error onto the stages of an investigation [9], discusses tool testing and its gaps [8], and, in a paper titled for the inference that a result which could not be found is not there, tool errors, tool limitations and user error [7]. Chae, Guercio and Arndt propose a repeatability- and error-centred protocol with documented reference data [4]. AutoDFBench scores tools and scripts by precision, recall and F1 on test cases built on NIST’s tool-testing program [15]. Vanini and colleagues treat the question whether a system clock was correct [14]. Külper and colleagues treat expected tool outputs as executable specifications and re-run them across software versions, which showed largely undocumented changes in the exported reports of one desktop tool across 25 versions [11]. Sunde and Dror analyse sources of cognitive and human error in digital forensic work [12].

2.3 Fault-based testing

Mutation testing inserts small faults into programs to see whether tests notice them [10]. We borrow the idea at the interface between a parser and a reader: we insert faults into a parser’s output and see whether the reader’s conclusion notices.

2.4 Position of this work

On 29 October 2026 we queried the arXiv, Zenodo and Crossref interfaces with 12 queries on parser failures, tool errors, fault injection, timestamp interpretation and examiner bias (arXiv with 10 more); OpenAlex, dblp and Semantic Scholar answered few or none because of rate limits and a bot check. We read the abstracts of the closest 14 works and six of them in full ([1], [3], [11], [13], [14], [15]); the reference list tags each. We found no study that measures how often a failure of a parser changes the conclusion drawn from its output, by failure class and by conclusion; Bulla’s preprint measures what the parser returns and whether it warns, and says it did not test decisions [3]. We do not claim that none exists: the publisher search pages of the ACM Digital Library, DFRWS and Forensic Science International: Digital Investigation were not reachable by script, and most full texts were not accessible. Because the SWGDE guide warns against rates for software errors [13], we report the sensitivity of a rule to a stated failure, not a rate of failure. What is new is the decision-level measurement, the direction of the change by kind of rule, and the coverage of cheap checks by class. The parse interface, the injections and the rules are engineering; the closed form for row loss is elementary. We compare no tools.

3 Method

3.1 Phones and the parse interface

We generated 300 Android phones with the calibrated profile of LAB-TR-0033 at full size, seed 3701 [20]. Single features of the profile were fitted to 14 measured phones; relations across stores were not reproduced, and native records are uniform in time. A phone has a message, a call and a media store where its profile has them (275, 278 and 300 phones), a package table, application-use events (271 phones) and a boot record. Median sizes are 2,507 messages, 1,557 calls and 930 media rows.

From a synthetic phone to a flip of a rule’s answerFour boxes in a column joined by arrows: a synthetic phone from the calibrated generator; the output of a parser as six reads; a failure injected into one read, of six classes; and a stated examiner rule that answers YES or NO. A flip is a change of the answer from the answer on the clean read. Four checks, on count, range, uniqueness and order across stores, are applied to the failing read.Synthetic phonegenerator of LAB-TR-0033,calibrated profileParser outputsix reads: boot, packages,usage, messages, calls, mediaInjected failureone read: empty, truncated,dropped, column, shift, duplicatedExaminer ruleten stated rules, YES or NO;flip = change from the clean readfour checks onthe failing read:count, range,uniqueness, orderthe clean readgives the answerto compare with
Figure 1: Method. A phone from the generator is read into a parse output; one read is replaced by what a failing parser would hand over; a rule answers YES or NO on the failing and on the clean read; the answers are compared.

A parse output has six reads: the boot record; the package table (name, first-install time, reason, system flag); application-use events; and the messages, calls and media, each as (identifier, time) in identifier order. It also holds each store’s counter kind and value and the extraction time. A round trip checks that this output read from a written SQLite file, including pending log frames, equals the output built from the tables: it was identical for 100 of 100 phones at scale 0.05 (test in the package). The failures hit one read at a time; the counter value is read separately and is not affected.

3.2 Failure classes

Table 2 defines the six classes and the 15 conditions. Each condition is applied to each read of each phone, with the replicates of the table, and every draw uses its own seeded generator, so a run is repeatable. Truncation keeps the oldest rows, because stores are read in identifier order and packages and application-use events in time order. For a one-row read (the boot record) truncation and dropping coincide with an empty read or leave it intact.

Table 2: Failure classes injected into one read of the parse output, with the 15 conditions of the study. Replicates are independent draws per phone and read; a condition with one replicate is deterministic.
ClassWhat the parser hands overConditionsReplicates
EMPTYNo rows from the read.one1
TRUNCThe first ⌊f·n⌋ rows in read order; the newest rows are lost.f = 0.9, 0.5, 0.11
DROPEach row lost independently with probability q.q = 0.05, 0.25, 0.63
COLUMNEvery time value comes from another column. Near: another timestamp of the record (for a package, the last-update time; for the boot record, the first password time; otherwise the true time plus or minus 1 min to 1 d, log-uniform). Gross: a column that is not a time (identifier, application index, install reason, 0) read as one.near, gross3
TZEvery time value shifted by h hours; the sign is drawn once per injection.h = 1, 6, 123
DUPEach row returned twice with probability r, the whole row including its identifier.r = 0.1, 0.5, 1.03

3.3 Decision rules

A rule stands in for an examiner’s conclusion (Table 3). It takes the output at face value: a row that is absent is a fact that is absent, and a read that returns nothing means nothing was recorded. This is the reading the Lab’s earlier work warns against [16]; here it is the object of study, not an assumption about examiners. The three counter rules estimate removed records as the counter minus the rows present, after rebasing a counter set near 109 [19]. Each phone gets 119 questions on average: 20 for each of the six existence rules where it has the data, one for each counter rule and one before-boot question. Half of the questions name a day on which the clean read has a supporting row (for the boot rule, a date within 30 days of the first boot); the others draw a day uniformly up to the extraction time, starting 60 days before the first boot (messages, calls, media and the boot rule), at the first boot (packages) or at the first event (application use). The question form follows LAB-TR-0029 [18]. The before-boot rule uses the first boot record that LAB-TR-0028 treats as the start of a device’s own life [17]. Questions are fixed across conditions, so the comparison is paired.

Table 3: The ten decision rules that stand in for examiner conclusions. Each returns YES or NO from a parse output and reads an empty or missing read as “nothing recorded”. The last two columns give the share of YES answers on the clean read and the number of questions over the 300 phones.
RuleQuestionReadsClean YES (%)Questions
reset before DThe device was first booted before day D.boot686,000
app installed on DPackage P was first installed on day D.packages506,000
app used on DApplication A was used on day D.usage events585,420
message on DA message is dated day D.messages755,500
call on DA call is dated day D.calls755,560
media on DA media item is dated day D.media726,000
messages removedRecords were removed from the store (the identifier counter exceeds the rows present, after rebasing a counter set near 109).messages and counter72275
calls removedThe same for calls.calls and counter91278
media removedThe same for media.media and counter100300
message before bootThe message store holds a message dated more than 1 h before the boot record.boot and messages49275

3.4 Flips, direction, and replication

A flip is a change of the answer from the answer on the clean read. A flip is hidden if the clean answer was YES and the answer on the failing read is NO, and invented in the other direction. We report the share of flips among the clean-YES answers (hidden) and among the clean-NO answers (invented) separately, because the mix of YES and NO depends on the questions and on the density of the data. For rules about existence, loss can only remove support, so a NO cannot become a YES; we count violations instead of assuming them. For the loss classes the hidden share of an existence answer with c supporting rows is qc, which we compare with the observed share. Intervals resample phones with replacement (400 draws), because a phone, not a question, is the unit of replication.

3.5 Cheap checks

Four checks look only at what the parser handed over, the extraction time and one independent count of the table. G1 compares the number of rows returned with the count. G2 flags a time before 2000 or more than a day after extraction. G3 flags a row that appears twice. G4 flags a package or application-use event more than an hour before the boot record, when a boot record was returned. A check detects a failure only if it fires on the failing read and not on the clean one; we report separately how often each fires on clean reads. The independent count is assumed correct, which favours G1.

3.6 Resemblance to measured failures

LAB-TR-0006 ran two parser suites on real images and found silent failures [16]. For each injected class we list the measured counterpart and say whether a failure of that kind was observed, only described as a condition, or not observed. Where the report gives a loss fraction we compare it with the loss fraction of an injected drop of the same number of rows (2,000 draws). Only the published numbers of that report are used; no image was opened.

3.7 Sensitivity

Two variants test whether the results depend on the data. The documentation-only profile of LAB-TR-0033 makes phones that are set up at first boot, with no restored records (150 phones, seed 3702). The bursty variant moves native records onto days drawn with log-normal weights (sigma 1.5), so that activity falls on fewer days (150 phones, seed 3703).

4 Results

4.1 The clean read

The 300 phones gave 35,608 questions. On the clean read 66% of the existence answers are YES, 88% of the removal answers are YES (the generator removes rows from almost every store), and 49% of the before-boot answers are YES. Against the generator’s ledger, a clean NO on a message, call or media day question was unsound (the ledger says present or unobservable) for 8%, 11% and 11% of the questions, so the rules are not exact even on a perfect parse. Flips measure the change a failure adds.

4.2 How often answers flip, and in which direction (RQ1, RQ2)

Row loss hides findings and does not invent them for existence rules. An empty read hid 100% of the YES answers; truncating to 90% of the rows hid 29%, to 50% 64%, to 10% 93%; dropping 5%, 25% and 60% of the rows hid 2.9%, 15.7% and 41.5% (Table 4, Figure 2). Not one of the 151,632 clean-NO existence answers (448,240 answers in all) turned to YES under a loss class (monotone rules: this tests the code). Duplicated rows changed no existence answer.

Table 4: Share of answers that flip, by failure condition and direction (percent). Hidden: the clean answer was YES and the answer on the failing read is NO. Invented: NO to YES. Existence rules are the six rules about a day, a package or the boot record; removal rules the three counter rules. Brackets: 95% interval, 300 phones resampled with replacement (400 draws). Clean YES answers: 22,816 existence, 753 removal, 270 before-boot; clean NO answers: 11,664, 100, 280. The before-boot rule reads two stores (boot and messages); its shares are over both. For the one-row boot read, truncation equals an empty read.
ConditionExistence hiddenExistence inventedRemoval hiddenRemoval inventedBefore-boot hiddenBefore-boot invented
Empty read100 [100–100]03.787.01000
Truncated, 90% kept29.0 [28.4–29.6]00.887.050.00
Truncated, 50% kept64.5 [63.8–65.2]02.487.050.00
Truncated, 10% kept93.3 [92.8–93.6]06.887.051.90
Rows dropped, 5%2.9 [2.6–3.2]001001.60
Rows dropped, 25%15.7 [14.9–16.4]0010014.10
Rows dropped, 60%41.5 [40.5–42.8]0010031.40
Wrong column, near25.6 [24.9–26.4]1.800039.6
Wrong column, gross82.2 [81.9–82.6]16.70050.050.0
Time shift, 1 h1.8 [1.6–1.9]0.60000
Time shift, 6 h10.5 [10.0–11.0]2.90008.9
Time shift, 12 h20.5 [19.8–21.3]5.30009.6
Duplicated rows, 10%0 [0–0]016.9000
Duplicated rows, 50%0 [0–0]046.7000
Duplicated rows, 100%0 [0–0]057.8000
Share of answers that flip, by rule and failure conditionA grid with ten rules in rows and fifteen failure conditions in columns; each cell is the percentage of the rule’s answers that changed from the answer on the clean read, over 300 synthetic phones. reset before D: empty 68, trunc 90% 68, trunc 50% 68, trunc 10% 68, drop 5% 3, drop 25% 17, drop 60% 42, column near 34, column gross 32, shift 1 h 0, shift 6 h 0, shift 12 h 1, dup 10% 0, dup 50% 0, dup 100% 0 ; app installed on D: empty 50, trunc 90% 9, trunc 50% 40, trunc 10% 50, drop 5% 3, drop 25% 12, drop 60% 30, column near 48, column gross 50, shift 1 h 2, shift 6 h 13, shift 12 h 25, dup 10% 0, dup 50% 0, dup 100% 0 ; app used on D: empty 58, trunc 90% 9, trunc 50% 31, trunc 10% 55, drop 5% 3, drop 25% 14, drop 60% 35, column near 9, column gross 58, shift 1 h 3, shift 6 h 16, shift 12 h 32, dup 10% 0, dup 50% 0, dup 100% 0 ; message on D: empty 75, trunc 90% 11, trunc 50% 39, trunc 10% 65, drop 5% 1, drop 25% 5, drop 60% 15, column near 3, column gross 75, shift 1 h 1, shift 6 h 5, shift 12 h 11, dup 10% 0, dup 50% 0, dup 100% 0 ; call on D: empty 75, trunc 90% 8, trunc 50% 38, trunc 10% 67, drop 5% 1, drop 25% 6, drop 60% 21, column near 4, column gross 75, shift 1 h 1, shift 6 h 7, shift 12 h 12, dup 10% 0, dup 50% 0, dup 100% 0 ; media on D: empty 72, trunc 90% 8, trunc 50% 39, trunc 10% 65, drop 5% 1, drop 25% 7, drop 60% 21, column near 4, column gross 72, shift 1 h 1, shift 6 h 7, shift 12 h 13, dup 10% 0, dup 50% 0, dup 100% 0 ; messages removed: empty 33, trunc 90% 25, trunc 50% 25, trunc 10% 26, drop 5% 28, drop 25% 28, drop 60% 28, column near 0, column gross 0, shift 1 h 0, shift 6 h 0, shift 12 h 0, dup 10% 30, dup 50% 52, dup 100% 59 ; calls removed: empty 9, trunc 90% 9, trunc 50% 9, trunc 10% 9, drop 5% 9, drop 25% 9, drop 60% 9, column near 0, column gross 0, shift 1 h 0, shift 6 h 0, shift 12 h 0, dup 10% 5, dup 50% 36, dup 100% 50 ; media removed: empty 0, trunc 90% 0, trunc 50% 4, trunc 10% 14, drop 5% 0, drop 25% 0, drop 60% 0, column near 0, column gross 0, shift 1 h 0, shift 6 h 0, shift 12 h 0, dup 10% 10, dup 50% 36, dup 100% 45 ; message before boot: empty 49, trunc 90% 25, trunc 50% 25, trunc 10% 25, drop 5% 1, drop 25% 7, drop 60% 15, column near 20, column gross 50, shift 1 h 0, shift 6 h 5, shift 12 h 5, dup 10% 0, dup 50% 0, dup 100% 0.emptytrunc 90%trunc 50%trunc 10%drop 5%drop 25%drop 60%column nearcolumn grossshift 1 hshift 6 hshift 12 hdup 10%dup 50%dup 100%reset before D68686868317423432001000app installed on D509405031230485021325000app used on D58931553143595831632000message on D7511396515153751511000call on D758386716214751712000media on D728396517214721713000messages removed3325252628282800000305259calls removed99999990000053650media removed0041400000000103645message before boot4925252517152050055000Share of answers that flip, percent:0under 55 to 2525 to 5050 or more
Figure 2: Share of answers that flip, percent, by rule (rows) and failure condition (columns), over 300 synthetic phones.

The counter rules move the other way. Where the clean answer was NO (no removal), any row loss made the rule report removals: dropping rows did so for 100% of those answers (900 of 900). The 900 answers are not 900 independent observations: they come from 100 clean-NO pairs of a rule and a phone (76 message stores and 24 call stores on 94 phones, the smallest holding 52 rows), each tested at three drop rates with three replicates, and every pair flipped in all nine draws. The exact 95% lower bound for the share of such pairs that flip is 96.4%. No media store was a clean NO. An empty read did so for 87 of the 100 pairs (exact 95% interval 79% to 93%). The reason is arithmetic: the counter stays where it was and the rows it should match are gone. Like the monotone case above, this follows from how the rule is built; what the measurement adds is how many stores carry a clean NO to lose. The answers that stayed NO were tables without a counter record (the plain rowid table), where the estimate comes from the rows themselves and truncation leaves it at zero. Duplicated rows push the other way and hid removals in 17%, 47% and 58% of the YES answers at 10%, 50% and 100% duplication. Loss also hid a few removals (truncation: 6.8% at the most). In a diagnostic of the first 120 phones this happened with an empty read for tables without a counter record, and with truncation mostly for tables with a counter set near 109 whose later rows were cut, so that the gap before the counter was read as the set.

Time faults move answers both ways. A shift of 1, 6 and 12 hours hid 1.8%, 10.5% and 20.5% of the existence answers and invented 0.6%, 2.9% and 5.3%. For the day rules on messages, calls and media the hidden shares were 1.1%, 6.9% and 13.1%: a shift moves a record across midnight with a chance that grows with the shift, and the share is lower on the denser documentation-only phones (Table 8). A near wrong column hid 96% of the install answers (a last-update time read for the first-install time), 50% of the boot answers (the first password time read for the boot time) and 3.9% of the day answers on messages, calls and media, and invented 3.3% of those. A gross wrong column behaved like an empty read for the day rules (100% hidden) and invented the answer YES to the boot question when the boot time became 0. The before-boot rule, which uses both the boot record and the messages, flipped whenever the boot record was lost (the answer YES became NO) and, under a wrong column, in both directions.

4.3 What governs the loss rate (RQ1)

For row loss the hidden share is predictable. A YES answer that rests on c rows is hidden by a drop with probability q to the power of c. Table 5 compares the observed share with the mean of this prediction over the YES answers; the largest difference is 1.5 percentage points, and the interval of the difference (phones resampled) contains zero in 18 of 18 cells. Figure 3 shows why density matters: with a quarter of the rows dropped, 25% of the answers supported by one row were hidden, 5% of those supported by two or three, and 0.1% of those supported by four or more. A day with one message is exposed, a day with ten is not. The install and boot rules rest on one row each, so they are exposed at the full drop rate.

Table 5: Hidden-answer share under a row drop: observed / predicted, percent. Predicted is the mean over the clean YES answers of q to the power of the number of rows that support the answer. Each cell rests on up to 12,972 clean YES answers (three replicates).
Ruleq = 0.05q = 0.25q = 0.6
reset before D4.3 / 5.025.7 / 25.061.5 / 60.0
app installed on D5.2 / 5.024.7 / 25.059.9 / 60.0
app used on D4.9 / 4.824.8 / 24.260.2 / 59.0
message on D1.1 / 1.26.4 / 6.720.7 / 20.8
call on D1.3 / 1.48.2 / 8.328.5 / 28.5
media on D1.6 / 1.69.2 / 9.128.7 / 28.2
Answers hidden by a 25 percent row drop, by number of supporting rowsBars give the share of YES answers that turned to NO when a quarter of the rows were dropped, for day questions on messages, calls and media and application-use questions, grouped by the number of rows that support the YES answer. The line on each bar marks the bound 0.25 to the power of the fewest rows in the group. 1 rows: 24.8 percent of 19,539 answers, bound 25.00 percent; 2-3 rows: 5.0 percent of 10,008 answers, bound 6.25 percent; 4-9 rows: 0.1 percent of 8,121 answers, bound 0.39 percent; 10+ rows: 0.0 percent of 9,585 answers, bound 0.00 percent.0102030Answers hidden by a 25% row drop, percent1n=19,5392-3n=10,0084-9n=8,12110+n=9,585rows that support the YES answerbound: 0.25 to the power of the fewest rows
Figure 3: Share of YES answers hidden when 25% of the rows are dropped, by the number of rows that support the answer (application-use, message, call and media rules; the install and boot rules always rest on one row).

4.4 What cheap checks see (RQ3)

Table 6 and Figure 4 give the share of flips each check would have exposed. G1 saw all 111,685 flips caused by loss and duplication, which follows from how the classes are built: they change the number of rows, and the count is assumed correct. The classes that keep the count are the ones that escape: of 25,680 flips from time shifts, the four checks saw 2.1%; of 18,468 flips from a near wrong column, 24% (the order check, when a wrong boot time falls after the first installs). A gross wrong column was seen in 93% of the flips by the range check. Across all conditions the four checks exposed 80% of 218,764 flips; across the time faults (time shifts and near wrong columns, 44,148 flips), 11% (5,038).

Table 6: Share of flips that each check would have exposed (percent), pooled over rules and severities; a check counts only if it fires on the failing read and not on the clean one. G1 count reconciliation, G2 range, G3 uniqueness, G4 order across stores. The last row gives the share of clean reads on which a check fires (G2: 12.4% of clean message, call and media reads).
Failure classFlipsG1G2G3G4Any
Empty read23,201100000100
Truncated read43,348100000100
Rows dropped42,394100000100
Wrong column, near18,4680002424
Wrong column, gross62,931093112993
Time shift25,68001022
Duplicated rows2,74210001000100
Clean reads that raise the check (1,724 reads)05.8005.8
Share of flips that cheap checks would have exposed, by failure classFor each failure class, the percentage of flipped answers, pooled over all rules and severities, for which the count check fired and for which any of the four checks fired on the failing read but not on the clean read. Empty read: count check 100.0, any of four checks 100.0, of 23,201 flips; Truncated: count check 100.0, any of four checks 100.0, of 43,348 flips; Rows dropped: count check 100.0, any of four checks 100.0, of 42,394 flips; Wrong column, near: count check 0.0, any of four checks 24.4, of 18,468 flips; Wrong column, gross: count check 0.0, any of four checks 92.5, of 62,931 flips; Time shift: count check 0.0, any of four checks 2.1, of 25,680 flips; Duplicated rows: count check 100.0, any of four checks 100.0, of 2,742 flips.0255075100Share of flips seen by the checks, percentEmpty readTruncatedRows droppedWrong column, nearWrong column, grossTime shiftDuplicated rowscount checkany of the four checks
Figure 4: Share of flips exposed by the count check and by any of the four checks, by failure class, percent.

The checks are not free of false alarms. The range check fired on 12.4%, 11.5% and 11.3% of clean message, call and media reads, because the generator steps the recorded clock on some phones (Table 6, last row). No check fired on a clean boot, package or usage read.

4.5 Resemblance to measured failures (RQ4)

Table 7 sets the six classes against LAB-TR-0006. Empty reads and dropped rows have measured counterparts: the report’s failures returned no rows on 3 of 4 images (and 3 of 1,450 rows on the fourth), 8 of 8 images, 2 of 4 images (a new parser of the Lab, before its fix) and 3 of 4 devices, and in the first-match case lost 56.8%, 61.8% and 60.0% of the rows on three devices (59.8% pooled). For the same numbers of rows, the central 95% of 2,000 injected drops of 60% lost 56.7% to 63.0%, 57.4% to 62.8% and 56.9% to 63.1% of them on the three devices, and each measured fraction lies inside its range. The 60% condition was chosen to match this loss, so this checks the size of the loss, not its mechanism: the measured loss was by user, the injected loss is by row. A wrong column, a time shift and duplicated rows have no observed failure of a released parser in that report. Their conditions and parameters rest on what the report describes as risks, on Bulla’s preprint (timestamp errors, a time of 1970 from a wrong representation) [3] and on our own choice, and are not validated by measurement.

Table 7: Injected classes and the failures measured in LAB-TR-0006. “Measured” means a parser was observed to behave so on real images; the numbers are those of that report. The Health Connect first-grant file and the damaged files concern new parsers of the Lab before release; the other instances are released parsers.
Injected classCounterpart in LAB-TR-0006What was measuredStatus
EMPTYMedia database, application list, Health Connect first-grant file, calendar and settings search (first-match pattern), damaged filesZero rows where 1 to 5,523 were stored: 3 of 4 images (3 of 1,450 on the fourth), 8 of 8 images, 2 of 4 images, 3 of 4 devices; six damaged variants of real files gave no rows and no exceptionMeasured
DROPApp-update database, first-match pattern returns one Android user’s copyOn three devices 494 of 870, 740 of 1,198 and 559 of 932 rows lost (56.8%, 61.8%, 60.0%); pooled 1,793 of 3,000 (59.8%). The loss is by user, not by rowMeasured
TRUNCTruncated and zeroed filesRead as empty at file level; no partial read observedMeasured as EMPTY only
COLUMNA table named for network traffic holds a lookup logTwo columns did not hold what their names suggest; found before release, no released parser was wrongRisk described
TZDevice-local time without a stored zone (SIM event log)A condition under which a zone error can occur; no failure measuredCondition only
DUPDoubling test: a duplicate view of a file must not change the countA test relation; no duplicated output was observedNone observed

4.6 Sensitivity to the data

The directions did not change (Table 8). The size of the day-rule shares did. On documentation-only phones, which hold more messages and media (medians 4,846 and 4,832 against 2,507 and 930), a quarter row drop hid 4.3% of the day answers against 8.0% on calibrated phones, and a 6-hour shift invented 6.9% against 5.1%. Truncation to 50% hid 27.8% on bursty phones against 52.3%, because activity falls on fewer days, so a day survives if any of its records does; the variant also re-dates records without changing identifiers, so truncation cuts random dates there and not the newest ones. A documentation-only phone has 2 clean NO removal answers, so its removal invention share rests on very few pairs.

Table 8: Sensitivity of the flip shares (percent) to the data. Calibrated: 300 phones of the main study. Documentation only: 150 phones from the uncalibrated profile of LAB-TR-0033 (set up at first boot, no restored records). Bursty: 150 phones of the calibrated profile with native records moved onto days drawn with log-normal weights (sigma 1.5). Day rules: messages, calls and media.
Condition and measureCalibratedDocumentation onlyBursty
Day rules hidden, empty read100100100
Day rules hidden, rows dropped 25%8.04.37.1
Day rules hidden, truncated 50%52.350.227.8
Day rules hidden, time shift 6 h6.93.46.3
Day rules invented, time shift 6 h5.16.99.2
Day rules hidden, wrong column near3.91.93.4
Removal rules invented, rows dropped 25%100100100
Removal rules hidden, duplicated 50%46.710041.1
Existence rules hidden, rows dropped 25%15.712.414.8

5 Discussion

What the numbers say. A silent failure that loses rows does not look the same to every question. A question about whether something exists is exposed only to hiding, and the exposure falls steeply with the number of rows that support the answer. A question that compares a counter with the rows present is exposed to inventing: the counter stays, the rows go, and a gap appears. A time fault is exposed to both and, of the classes studied, is the hardest to see. A reader who asks only whether a table was empty misses the second and third cases.

For tool authors. A count of rows read against rows in the table, reported with every artifact, would have exposed every flip caused by loss or duplication here. It does not expose a wrong column or a time shift; a range check helps against a gross error and fires on phones whose clock stepped. A statement of the time base in which each column was read would address the second case, which the checks of this report cannot.

For examiners. An absence is a claim about the parser as well as about the phone. The shares in Table 4 give the order of magnitude of that claim under stated faults, not a rate for any tool. The finding that a counter rule invents removals when rows are lost is a reason to read counter-based gaps together with a row count of the same read.

Relation to earlier work. The Lab’s report on silent failures measured how parsers fail on real images [16]; Bulla measured whether a parser warns [3]; Azahari and colleagues measured how often schemas drift [1]. This report adds the step from a failure to a conclusion. It does not replace those measurements: it needs them for its failure rates, which we do not claim to know.

6 Threats to Validity and Limitations

Internal. The failures are injected into a parser’s output with parameters we chose; they are not produced by a parser, and real failures may be correlated across reads or follow the data in ways the independent drop does not (the measured first-match loss was by user). The rules are simple and read the output at face value; examiners compare sources, so flips overstate the effect on a careful reader, and a rule that is not at face value could be more or less sensitive. The count check is given a correct independent count, which favours it. The counter rules assume that the counter is read correctly while the rows are not; a parser that fails to open the database would lose both, and the answer would then depend on how a rule treats a missing counter. The closed form for row loss is elementary; its agreement with the data tests the code.

External. The phones are synthetic. Single features of the generator match 14 measured Android phones, 12 of them Samsung; relations across stores do not, native records are uniform in time, and the documentation-only and bursty variants show that day-level shares depend on this. The bursty variant re-dates records without changing their identifiers, so it breaks the order of identifiers and dates. No iOS phone, bug report or application database beyond the stores of the generator is modelled. The questions are 50% on days with a supporting record by construction.

Construct. A flip is a change from the answer on the clean read, not an error against the world: the rules are not exact even on a clean read (Section 4.1). The resemblance to LAB-TR-0006 covers two of six classes and, for dropped rows, only the size of a loss, not its mechanism. We make no statement about how often parsers fail.

Limitations. One seed per sample; intervals reflect the phones, not the choice of seed. The removal rules rest on 100 clean-NO pairs from 94 phones, none of them media stores. A human-subject study would be needed to say how examiners respond to a missing or wrong table.

7 Conclusion

On 300 synthetic phones, injected row loss hid findings of existence rules and, as the rules are monotone, never invented them, from 2.9% of the YES answers when 5% of the rows were dropped to all of them when the read was empty. The same loss made the counter rules report removals that had not happened. Time faults moved answers both ways and were seen by the cheap checks in 11% of the flips; loss and duplication were seen by a count check by construction. Two of the six failure classes have a measured counterpart in earlier real-image work of the Lab. Future work: a study of examiners reading wrong tables, failure rates of parsers on natural drift, rules that use several sources, and iOS.

Artifact Availability

The code, the generator it uses, the profiles, the per-phone counts behind every table and figure, the summaries and the published numbers of LAB-TR-0006 that Table 7 uses will be released as one package in the Lab's public artifacts repository, with no release date set (Python standard library only; code under the MIT licence, profiles, results and text under CC BY 4.0). The package is not public yet, and the sentences that follow describe it as planned. Every table and figure of this report reproduces from the package, because the study uses no private data; the main run takes about 10 minutes on one core. The open-source suites ALEAPP and iLEAPP are mentioned only as the subjects of an earlier study [2].

Data Handling Statement

All devices in this study are synthetic. They were made by a generator whose profile holds summaries of features over 14 phones from the Lab’s research corpus of mobile device extractions, read only; no extraction was opened for this study. The report gives aggregate counts and shares. It contains no identifiers, personal data, message or file content, or case information. The earlier real-image numbers in Table 7 are those published in LAB-TR-0006. The sample phones contain invented identifiers only.

Declaration of AI Assistance

The authors conceived the research questions and directed the work. The experiment code, the data checks and the first draft of this report were produced with AI assistance (Anthropic Claude). The authors reviewed the results and the text and are responsible for the content.

References

  1. Afiqah M. Azahari, Andrea Oliveri, and Davide Balzarotti. 2026. Resilience of forensic evidence acquisition under database schema drift. Forensic Science International: Digital Investigation 56 (2026), 302059. https://doi.org/10.1016/j.fsidi.2026.302059 (Full text read, in the preprint form hosted by the authors’ institution.)
  2. Alexis Brignoni et al. [n. d.]. ALEAPP and iLEAPP. GitHub repositories (MIT licence). Retrieved October 29, 2026 from https://github.com/abrignoni/ALEAPP and https://github.com/abrignoni/iLEAPP (Existence confirmed; not run in this study.)
  3. Tarun Preetham Bulla. 2026. Failure transparency in Android forensic parsing under schema and representation drift: A controlled ALEAPP microbenchmark. Research Square preprint, posted September 7, 2026. https://doi.org/10.21203/rs.3.rs-10927741/v1 (Full text read. Preprint; the page does not state a peer review.)
  4. Younghun Chae, Angela Guercio, and Timothy Arndt. 2026. A repeatability- and error-centered validation protocol for mobile device forensic workflows. Journal of Cybersecurity, Digital Forensics and Jurisprudence 2 (2026), 19–34. https://doi.org/10.65879/3070-5789.2026.02.03 (Abstract read; full text not accessible.)
  5. Angelina A. Claij-Swart, Erik Oudsen, Bouke Timbermont, Christopher Hargreaves, and Lena L. Voigt. 2025. Automatically generating digital forensic reference data triggered by mobile application updates. Forensic Science International: Digital Investigation 54 (2025), 301985. https://doi.org/10.1016/j.fsidi.2025.301985 (Abstract read; full text not accessible.)
  6. Christopher Hargreaves, Alex Nelson, and Eoghan Casey. 2024. An abstract model for digital forensic analysis tools: A foundation for systematic error mitigation analysis. Forensic Science International: Digital Investigation 48 (2024), 301679. https://doi.org/10.1016/j.fsidi.2023.301679 (Abstract read; full text not accessible.)
  7. Graeme Horsman. 2018. “I couldn’t find it your honour, it mustn’t be there!” — Tool errors, tool limitations and user error in digital forensics. Science & Justice 58, 6 (2018), 433–440. https://doi.org/10.1016/j.scijus.2018.04.001 (Abstract read (repository summary); full text not accessible.)
  8. Graeme Horsman. 2019. Tool testing and reliability issues in the field of digital forensics. Digital Investigation 28 (2019), 163–175. https://doi.org/10.1016/j.diin.2019.01.009 (Abstract read; full text not accessible.)
  9. Graeme Horsman. 2024. Sources of error in digital forensics. Forensic Science International: Digital Investigation 48 (2024), 301693. https://doi.org/10.1016/j.fsidi.2024.301693 (Abstract read (repository copy); full text not accessible.)
  10. Yue Jia and Mark Harman. 2011. An analysis and survey of the development of mutation testing. IEEE Transactions on Software Engineering 37, 5 (2011), 649–678. https://doi.org/10.1109/TSE.2010.62 (Abstract read; full text not read.)
  11. Michael Külper, Martin Lambertz, and Mariia Rybalka. 2026. Do you dare to try Test-Driven Forensics? Increasing trust in desktop forensics with ADARE. arXiv:2605.28476. https://arxiv.org/abs/2605.28476 (Full text read.)
  12. Nina Sunde and Itiel E. Dror. 2019. Cognitive and human factors in digital forensics: Problems, challenges, and the way forward. Digital Investigation 29 (2019), 101–108. https://doi.org/10.1016/j.diin.2019.03.011 (Abstract read; full text not accessible.)
  13. Scientific Working Group on Digital Evidence. 2018. SWGDE establishing confidence in digital and multimedia evidence forensic results by error mitigation analysis. Document 12-Q-001, version 2.0, November 20, 2018. https://www.swgde.org/12-q-001 (Full text read.)
  14. Céline Vanini, Christopher J. Hargreaves, Harm van Beek, and Frank Breitinger. 2024. Was the clock correct? Exploring timestamp interpretation through time anchors for digital forensic event reconstruction. Forensic Science International: Digital Investigation 49 (2024), 301759. https://doi.org/10.1016/j.fsidi.2024.301759 (Full text read, repository copy.)
  15. Akila Wickramasekara, Tharusha Mihiranga, Aruna Withanage, Buddhima Weerasinghe, Frank Breitinger, John Sheppard, and Mark Scanlon. 2025. AutoDFBench 1.0: A benchmarking framework for digital forensic tool testing and generated code evaluation. arXiv:2512.16965. https://arxiv.org/abs/2512.16965 (Full text read.)
  16. Daniel Addai. 2026. Empty Is Not Absent: Silent Failure Modes in Open-Source Mobile Forensic Parsers on iOS 26 and Android 16. Lab Technical Report LAB-TR-0006, version 1.0. SectraTEK Lab, Prudential Associates. https://doi.org/10.5281/zenodo.23717929
  17. Daniel Addai, Selorm Adjabeng, Kingsley Albert Egyir, and Sanders Larweh Tetteh. 2026. Where a Phone’s Own Life Begins: Device-Life Boundary Indicators and Restored Versus Native Records on Android. Lab Technical Report LAB-TR-0028, version 1.0. SectraTEK Lab, Prudential Associates. https://lab.sectratek.com/research/reports/lab-tr-0028/
  18. Daniel Addai, Kingsley Albert Egyir, Sanders Larweh Tetteh, and Selorm Adjabeng. 2026. Can This Phone Answer This Question? Measuring the Answerability of Date-Bound Questions from Device Life, Retention and Record Semantics. Lab Technical Report LAB-TR-0029, version 1.0. SectraTEK Lab, Prudential Associates. https://lab.sectratek.com/research/reports/lab-tr-0029/
  19. Daniel Addai, Sanders Larweh Tetteh, Selorm Adjabeng, and Kingsley Albert Egyir. 2026. How Many Records Are Gone? Upper Bounds from Identifier Counters in Android Media and Message Stores. Lab Technical Report LAB-TR-0030, version 1.0. SectraTEK Lab, Prudential Associates. https://lab.sectratek.com/research/reports/lab-tr-0030/
  20. Daniel Addai, Sanders Larweh Tetteh, Selorm Adjabeng, and Kingsley Albert Egyir. 2026. Synthetic Android Phones That Match Measured Ones Feature by Feature but Not Across Stores: A Calibrated Generator and Benchmark. Lab Technical Report LAB-TR-0033, version 1.0. SectraTEK Lab, Prudential Associates. https://lab.sectratek.com/research/reports/lab-tr-0033/

Cite and download

Cite as

Daniel Addai, Selorm Adjabeng, Kingsley Albert Egyir, and Sanders Larweh Tetteh. 2026. Silent Parser Failures Hide Findings and Invent Deletions Under Stated Decision Rules: A Fault-Injection Study on Synthetic Phones. Lab Technical Report LAB-TR-0037, version 1.0. SectraTEK Lab, Prudential Associates. Preprint, not peer reviewed. https://lab.sectratek.com/research/reports/lab-tr-0037/

Citation guide
lab-tr-0037.bib
@techreport{addai2026labtr0037,
  author      = {Addai, Daniel and Adjabeng, Selorm and Egyir, Kingsley Albert and Tetteh, Sanders Larweh},
  title       = {Silent Parser Failures Hide Findings and Invent Deletions Under Stated Decision Rules: A Fault-Injection Study on Synthetic Phones},
  institution = {SectraTEK Lab, Prudential Associates},
  type        = {Lab Technical Report},
  number      = {LAB-TR-0037},
  year        = {2026},
  month       = oct,
  howpublished = {https://lab.sectratek.com/research/reports/lab-tr-0037/},
  note        = {Version 1.0, preprint, not peer reviewed. CC BY 4.0}
}

Licence: CC BY 4.0. The print layout of this page is set for US Letter in two columns.

Versions and corrections

VersionDateChange
1.02026-10-29First release.

Corrections: none so far. Errors can be reported through the corrections page.