Skip to download

Measured API behavior / synthetic fault injection

Parquet checksum and read-coverage observations

9 read cases across 3 repetitions show how checksum presence, verification and selected columns or row groups change detection of one deliberate payload bit flip.

Download CSV27 observations / 7 columns

Metadata and hashes / Raw JSON / Full analysis

Method

Write two deterministic fixtures with/without page CRC, flip one payload bit in copies, compare nine read scopes/settings against complete expected selected values; repeat on fresh temporary files. Each fixture has 128 rows in two 64-row groups and two required INT64 columns. Compression and dictionary encoding are disabled. The harness changes exactly one bit in row 17 of the first measurement chunk, from 100017 to 100016; these integers have no physical units.

First repetition. Matches describe selected data only; metadata-readable does not mean payload-verified.
CaseVerifyScopeOutcome
clean-checkedtrueall-datamatches-selected-data
corrupt-defaultdefaultall-datawrong-values
corrupt-check-offfalseall-datawrong-values
corrupt-check-ontrueall-datachecksum-error
projection-check-ontrueid-onlymatches-selected-data
other-group-check-ontruerow-group-1matches-selected-data
metadata-onlynot-applicablemetadatametadata-readable
absent-crc-check-ontrueall-datawrong-values
clean-no-crc-check-ontrueall-datamatches-selected-data

Interpretation

The full checked read detects the deliberately altered checksummed payload. Default verification, disabled verification and absent-CRC cases return one incorrect value. Reading only the unmodified column or second row group succeeds without establishing anything about the damaged chunk. All 3 repeats agree; this is not an estimate of real-world error frequency.

Reproduce

Download the harness and pinned requirements together. It refuses existing output paths, creates disposable temporary fixtures only, verifies complete selected values and uses runtime checks that remain enabled with Python optimization. The dataset generator validates the raw evidence before flattening it into CSV.

python3 -m venv .venv
.venv/bin/pip install --only-binary=:all: -r parquet-integrity-requirements.txt
.venv/bin/python parquet-integrity.py --repetitions 3 --output observations.json

Measured environment: Python 3.12.3, PyArrow / Arrow C++ 21.0.0, Linux 6.8.0-146-generic, x86_64. File offsets, before/after hashes, mismatch coordinates and error text are retained in raw JSON. The pin identifies the tested version, not a recommendation that it is the latest release.

Limits

Supplement: footer statistics and query completeness

Seven additional cases, each repeated three times, isolate metadata-driven row-group exclusion. The original 27 payload observations above remain unchanged. Every supplementary read enables page checksum verification.

The generated file contains 128 synthetic rows and four checksummed pages. A structured Thrift edit raises the first measurement group's stored minimum from 100000 to 100032 in both minimum fields, leaving all page bytes unchanged. The predicate measurement = 100017 then returns zero rows. A full checked scan returns all original values, and filtering it in memory recovers id 17. Removing the affected statistics or using wider valid bounds also recovers that row.

First repetition: returned and expected row counts. This deliberately invalid metadata is not a sample of field errors.
CaseReadTarget
clean-filtered11
narrow-filtered01
absent-filtered11
wide-filtered11
narrow-full-scan128128
narrow-post-scan-filter11
body-fault-positive-controlCRC error128

The harness verifies byte-identical page regions, independently recomputes all four CRCs, compares complete decoded tables, inspects selected row groups and checks a deliberately changed page as a positive CRC-detection control. A separate bounds comparison detects the invalid minimum. The full scan alone does not report it.

Supplementary CSV: 21 observations / Raw results and byte offsets / Provenance and column definitions / Validator and CSV generator

Download the statistics harness, pinned requirements and official Parquet 2.10.0 Thrift schema. The runner rejects any schema whose SHA-256 differs from its recorded pin. It creates private disposable fixtures and never edits a supplied Parquet file. Existing output paths are refused. Use normal Python or -O; the pinned Thrift parser requires docstrings and does not support -OO.

python3 -m venv .stats-venv
.stats-venv/bin/pip install --only-binary=:all: -r parquet-statistics-requirements.txt
.stats-venv/bin/python parquet-statistics.py --schema parquet.thrift --output observations.json

Tested packages: PyArrow 21.0.0, thriftpy2 0.5.3, ply 3.11 and six 1.17.0. Environment and code hashes are in the supplementary metadata. One implementation and host; deliberately selected, structurally valid but semantically invalid metadata. Not a spontaneous bit-error model, prevalence estimate, security exploit, benchmark or test of encrypted, compressed, nested or dictionary files. Repetitions are not independent reliability trials.

Format and implementation evidence: Statistics and page CRC scope; Arrow 21.0 row-group pruning. CC0-1.0 for Hesela's original code and observations; dependencies and downloaded Apache schema retain their own licenses.

Column definitions

repetition
One-based repeat of the same deterministic experiment; not an independent reliability trial.
case
Controlled read case identifier.
verification
Page checksum verification: true, false, default (false in PyArrow 21.0.0), or not-applicable for metadata-only inspection.
scope
Selected data or metadata; success describes only this scope.
outcome
Observed return or checksum exception, compared with expected selected payload.
rows
Returned rows, or declared rows for metadata; empty when checksum error prevents a result.
mismatchCount
Number of differing selected cells; empty for metadata or an error, not a claim of zero errors.

Sources and license

CC0-1.0 for Hesela's original harness and observations; Apache libraries and documentation retain their own licenses.

  1. Apache Parquet: page checksumming
  2. Apache Arrow 21.0: read_table checksum verification and column selection
  3. Apache Arrow 21.0: write_table page checksum option
  4. Apache Arrow 21.0.0: SerializedPageReader checksum presence guard
  5. Apache Parquet: PLAIN INT64 encoding
  6. Apache Parquet: file, column and page metadata

Definitions: Apache Parquet / Parquet page checksum / row group / column chunk / zone map.

Published by Hesela team

Report a correction · Editorial standards · Reuse guidance

Cite this page
Hesela team. Parquet checksum and read-coverage observations. Hesela. https://hesela.dev/datasets/parquet-integrity-boundaries/