thanos-io/thanos · error
read parquet metadata files
Error message
read parquet metadata files
What it means
Returned when one or more of the concurrently executed parquet metadata file reads failed (merrs aggregated). It wraps merrs.Err() with 'read parquet metadata files', distinct from the bucket iteration error above it.
Solutions
- Check the inner aggregated errors for the specific file paths and root causes
- Delete or repair corrupt/truncated parquet metadata files, or re-run the parquet converter
- Verify read permissions on the parquet metadata prefix
- Retry if the underlying errors are transient (throttling, network)
Defensive patterns
Strategy: try-catch
Try / catch
if err := refreshMigratedBlocks(ctx); err != nil {
var errs []error
if errors.As(err, &errs) {
for _, e := range errs { log.Printf("parquet meta read: %v", e) }
}
// keep previous migrated-blocks set rather than wiping it
} Prevention
- Ensure the converter finishes writes before readers scan
- Set correct GetObject IAM permissions
- Handle throttling with reduced concurrency/backoff
- Delete corrupt metadata files instead of failing every scan
When it happens
Trigger: Any readMigratedBlocksFromParquetMetadata failure for a listed parquet metadata file — Get errors, io.ReadAll errors, easyproto field parse failures — aggregated by the errgroup workers.
Common situations: Objects deleted between listing and reading; truncated parquet metadata from an interrupted parquet conversion; permission or throttling errors on Get.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- failed to read parquet metadata from
- iterate bucket for parquet metadata
- get parquet metadata file
- read parquet metadata file
- create meta fetcher
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/3f142cfb71ae6d92.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/fetcher.go:1142
return f.bkt.Iter(ctx, "", func(name string) error {
if path.Base(name) == parquetMetaFileName {
select {
case ch <- name:
case <-ctx.Done():
return ctx.Err()
}
}
return nil
}, objstore.WithRecursiveIter())
})
if err := eg.Wait(); err != nil {
return errors.Wrap(err, "iterate bucket for parquet metadata")
}
if len(merrs) > 0 {
return errors.Wrap(merrs.Err(), "read parquet metadata files")
}
// NOTE(GiedriusS): we need to be extra careful here because Parquet converter trims chunks exactly to the day's range.
// The input to the Parquet converter might not be aligned exactly so we NEED to have some overlap.
// So, only delete metas if the migrated blocks cover each day *fully*.
for id := range filterMigratedBlocksByDayCoverage(allMigratedBlocks, metas) {
delete(metas, id)
synced.WithLabelValues("parquet-converted").Inc()
}
return nil
}
func filterMigratedBlocksByDayCoverage(migratedBlocks map[ulid.ULID]struct{}, metas map[ulid.ULID]*metadata.Meta) map[ulid.ULID]struct{} {
type blockRange struct {
id ulid.ULID
minTime, maxTime int64
}View on GitHub (pinned to 35b8b99117)