Skip to content

[Parquet][Python][Dataset] dataset(...).to_table() sometimes returns a truncated table instead of raising when one listed Parquet fragment cannot be opened (freshly written files) #51495

Description

@PepijnBrasseur

Describe the bug, including details regarding any error messages, version, and platform.

Summary

A pyarrow.dataset built from an explicit list of Parquet files, one of which is not a valid Parquet file, is expected to raise on to_table(). It usually does. Occasionally it instead returns a table containing only the rows of the file(s) that sort before the invalid fragment, with no exception. It happens only when the files were written immediately before the scan (a fresh directory per iteration); reusing the same files never reproduced it. Seen on Windows and on Linux, threaded and unthreaded.

Environment

  Windows Linux
pyarrow 23.0.1 23.0.1
Python 3.11.1 3.11.15
OS Windows 11, build 26200 (platform.platform() → Windows-10-10.0.26200-SP0) Ubuntu 24.04.4 LTS (x86_64; a cloud workspace, the same class on every run)
filesystem NTFS (local disk, the system temp directory) ext4 on a virtual disk, the system temp directory

What was checked

  • The file list is complete when the scan is short. On a truncated read, the listed paths included the invalid file and the dataset held all 5 fragments (fragment count = number of listed files) — the scan stopped early and returned without error. A fragment-count check before the scan therefore cannot detect it.
  • A 0-byte invalid file in the same position raises too (in the same test shape) — the truncation is not an empty file being skipped.
  • Threading is not the variable: it reproduces with use_threads=False on both platforms.
  • Freshness matters: 0 truncations in 3,600 reads of reused files, against the fresh-file rates above. Why fresh files matter is not understood.
  • The shape of the failing fragment matters: the 25-byte non-Parquet file truncates; a half-written Parquet file raised every time in 6,000 tries. Not understood.

What remains as candidates: the dataset scanner's handling of a fragment-open error, or something in the filesystem beneath it for files closed moments earlier — the two cannot be told apart from here.

Workaround in use

Opening every listed file's footer independently before the scan (pyarrow.parquet.ParquetFile(path).metadata) turns the silent truncation into a raise (0 truncations in 2,000 tries on the Windows reproduction); comparing the rows read with the rows the footers declare backstops the case where a footer opens but its data does not.

Component(s)

Python, Parquet

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions