thanos-io/thanos · error
read symbols
Error message
read symbols
What it means
Thrown when index.NewSymbols fails while loading the symbol table from the index file, using the offset recorded in the index-header TOC. It indicates the symbol table section of the source index is unreadable, or the index version recorded in the index-header does not match the actual index format.
Solutions
- Regenerate the index-header file (delete it from the bucket so Thanos recreates it from the index)
- Verify the index file integrity and that index-header and index belong to the same block
- Ensure Prometheus/Thanos versions are consistent with the block format versions
- Re-upload the affected block from a healthy source
Defensive patterns
Strategy: validation
Validate before calling
if st, err := os.Stat(indexPath); err != nil || st.Size() == 0 { /* restore/re-upload block before building index-header */ } Try / catch
if err != nil && strings.Contains(err.Error(), "read symbols") { regenerate index-header; if persists, quarantine block } Prevention
- Keep index-header and index files from the same build together
- Verify index file checksum after upload/download
- Pin Thanos/Prometheus versions compatible with your block formats
When it happens
Trigger: NewBinaryReader parses the index-header successfully but index.NewSymbols(r.b, r.indexVersion, toc.Symbols) fails because the symbol table offset is wrong, the symbol section is corrupt, or indexVersion (FormatV1/V2) is inconsistent with the data.
Common situations: Blocks uploaded by a different Prometheus/Thanos version than the reader expects; truncated index files; index-header generated from a different index than the one being read (mismatched pair in storage).
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/fddd9d19bf44162a.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/block/indexheader/binary_reader.go:693
}
r.version = int(r.b.Range(4, 5)[0])
r.indexVersion = int(r.b.Range(5, 6)[0])
r.indexLastPostingEnd = int64(binary.BigEndian.Uint64(r.b.Range(6, headerLen)))
if r.version != BinaryFormatV1 {
return errors.Errorf("unknown index header file version %d", r.version)
}
r.toc, err = newBinaryTOCFromByteSlice(r.b)
if err != nil {
return errors.Wrap(err, "read index header TOC")
}
// TODO(bwplotka): Consider contributing to Prometheus to allow specifying custom number for symbolsFactor.
r.symbols, err = index.NewSymbols(r.b, r.indexVersion, int(r.toc.Symbols))
if err != nil {
return errors.Wrap(err, "read symbols")
}
var lastName, lastValue []byte
if r.indexVersion == index.FormatV1 {
// Earlier V1 formats don't have a sorted postings offset table, so
// load the whole offset table into memory.
r.postingsV1 = map[string]map[string]index.Range{}
var prevRng index.Range
if err := index.ReadPostingsOffsetTable(r.b, r.toc.PostingsOffsetTable, func(name, value []byte, postingsOffset uint64, _ int) error {
if lastName != nil {
prevRng.End = int64(postingsOffset - crc32.Size)
r.postingsV1[string(lastName)][string(lastValue)] = prevRng
}
if _, ok := r.postingsV1[string(name)]; !ok {
r.postingsV1[string(name)] = map[string]index.Range{}
r.postings[string(name)] = nil // Used to get a list of labelnames in places.View on GitHub (pinned to 35b8b99117)