thanos-io/thanos · error
postings
Error message
postings
What it means
This error wraps a failure from IndexReader.Postings(ctx, key, value) in block.Rewrite (pkg/block/index.go:597), where the code fetches the all-postings list using index.AllPostingsKey() to rebuild the postings index. It indicates the source index file's postings section cannot be read or decoded — a corrupt/truncated postings offset table — rather than a symbol or series problem.
Solutions
- Restore the block from backup/replica or delete the corrupt block and let TSDB re-ingest or re-compact from upstream data.
- Use promtool tsdb dump/analyze to confirm which index sections are readable and gauge data loss scope.
- Check the block's index file size and checksums if the block was copied between nodes; re-copy if truncated.
- Verify the reading Prometheus/promtool version is compatible with the block's index format version.
Example fix
// before: rewrite proceeds and fails on unreadable postings
err := block.Rewrite(ctx, meta, src, dst, indexr, chunkr, nil)
// after: pre-validate that all-postings are readable before rewrite
_, err := indexr.Postings(ctx, index.AllPostingsKey())
if err != nil { return fmt.Errorf("source index unreadable, restore block: %w", err) }
return block.Rewrite(ctx, meta, src, dst, indexr, chunkr, nil) Defensive patterns
Strategy: validation
Validate before calling
all, err := indexr.Postings(ctx, index.AllPostingsKey())
if err != nil { return fmt.Errorf("source index postings unreadable; restore block: %w", err) }
defer all.Close() Type guard
func isPostingsError(err error) bool { return err != nil && strings.Contains(err.Error(), "postings") } Try / catch
if err := block.Rewrite(ctx, meta, src, dst, indexr, chunkr, nil); err != nil {
if strings.Contains(err.Error(), "postings") {
// postings section corrupt: quarantine block, do not retry rewrite
}
return err
} Prevention
- Pre-flight postings readability before launching a long repair
- Verify index file integrity (size/checksum) after any block transfer
- Keep Prometheus/promtool version compatible with block index format version
- Quarantine corrupt blocks promptly so compaction skips them
When it happens
Trigger: indexr.Postings(ctx, AllPostingsName, AllPostingsListValue) failing while reading the postings offset table for the special all-postings key during rewrite/Repair.
Common situations: Blocks damaged by crash during compaction; disk-level corruption; manually copied blocks missing parts of the index file; promtool repair on blocks produced by an older Prometheus index format.
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
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/9d708f66230606d4.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/index.go:597
indexr tsdb.IndexReader, chunkr tsdb.ChunkReader,
indexw tsdb.IndexWriter, chunkw tsdb.ChunkWriter,
meta *metadata.Meta,
ignoreChkFns []ignoreFnType,
) error {
symbols := indexr.Symbols()
for symbols.Next() {
if err := indexw.AddSymbol(symbols.At()); err != nil {
return errors.Wrap(err, "add symbol")
}
}
if symbols.Err() != nil {
return errors.Wrap(symbols.Err(), "next symbol")
}
key, value := index.AllPostingsKey()
all, err := indexr.Postings(ctx, key, value)
if err != nil {
return errors.Wrap(err, "postings")
}
all = indexr.SortedPostings(all)
// We fully rebuild the postings list index from merged series.
var (
postings = index.NewMemPostings()
values = map[string]stringset{}
i = storage.SeriesRef(0)
series = []seriesRepair{}
)
var builder labels.ScratchBuilder
var chks []chunks.Meta
for all.Next() {
id := all.At()
if err := indexr.Series(id, &builder, &chks); err != nil {
return errors.Wrap(err, "series")View on GitHub (pinned to 35b8b99117)