thanos-io/thanos · error
iterate bucket for parquet metadata
Error message
iterate bucket for parquet metadata
What it means
Returned when the errgroup waiting on the concurrent bucket iteration for parquet metadata files fails. It wraps the first error from the iter WithReportingBkt iteration callback (e.g. listing errors from the object store).
Solutions
- Look at the wrapped inner error to distinguish a listing error from a read error (read errors surface separately via the next wrap)
- Check bucket List permissions and endpoint/credentials config
- Retry; transient object-store failures typically resolve
- Ensure the context is not being canceled prematurely (timeouts, shutdown ordering)
Defensive patterns
Strategy: retry
Try / catch
if err := scanParquetMetadata(ctx); err != nil {
if errors.Is(err, context.Canceled) { return err }
return retry.WithBackoff(ctx, scanParquetMetadata, 3)
} Prevention
- Verify ListObjects permission on the prefix
- Keep contexts alive long enough for full bucket iteration
- Check bucket endpoint/credentials config early at startup
- Retry transient listing failures with backoff
When it happens
Trigger: The objstore.Iter (with WithRecursiveIter) over the parquet metadata prefix returns an error while listing objects — bucket API failures, context cancellation, or a wrapped readMigratedBlocksFromParquetMetadata error propagated via the errgroup (the per-file read errors themselves are collected separately).
Common situations: Bucket unavailable or throttled during listing; IAM lacking ListObjects permission; context canceled (shutdown/deadline) mid-iteration; misconfigured bucket endpoint.
Related errors
- failed to read parquet metadata from
- read parquet metadata files
- 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/06ddf8be5ed5118b.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/fetcher.go:1138
}
eg.Go(func() error {
defer close(ch)
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{} {View on GitHub (pinned to 35b8b99117)