thanos-io/thanos · error
unknown segment file for index
Error message
unknown segment file for index %d
What it means
bucketBlock.readChunkRange validates the segment index against the block's chunkObjs list before reading. If seq is negative or >= len(chunkObjs), meaning the caller asked for a segment file that does not exist in this block's index-header/meta, it returns 'unknown segment file for index %d'. It signals a caller/contract violation or a stale block view, not a storage failure.
Solutions
- Reload block metadata (remove stale cached blocks via store-gateway reload or restart) so chunkObjs matches the actual bucket state.
- Verify the index header file for the block lists the expected segment; re-download or use Thanos tools to inspect.
- Check for concurrent block deletion/compaction racing with reads; ensure compactor retention/cleanup is not removing blocks mid-query.
- If reproducible on a healthy block, file a bug with the block ID and query; it indicates internal index math went wrong.
Defensive patterns
Strategy: validation
Validate before calling
if seq < 0 || seq >= len(block.ChunkObjs()) {
// refresh block metadata before retrying
err := block.Reload(ctx)
} Type guard
func validSegment(seq int, objs []string) bool { return seq >= 0 && seq < len(objs) } Try / catch
if err != nil && strings.Contains(err.Error(), "unknown segment file") {
// reload block list / resync store-gateway before retry
} Prevention
- Keep store-gateway block sync interval low so cached refs track bucket state
- Avoid deleting blocks while queries are in flight
- Validate index-header integrity during block sync
When it happens
Trigger: Calling readChunkRange with a seq outside [0, len(b.chunkObjs)); happens when a cached ChunkObj/AggrChunk reference points to a segment that is no longer listed in the block's index header, or bad partition arithmetic on compound chunks.
Common situations: Store-gateway caching series/chunks across block reloads, corrupted or partially-uploaded index header, blocks replaced/deleted in the bucket while cached references persist, bugs in external tools computing chunk offsets.
Related errors
- empty chunks for series
- open chunks
- chunk read
- iterate chunk while re-encoding
- populateWithDelChunkSeriesIterator: unexpected empty chunk…
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/3bd0077379f2e511.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/store/bucket.go:2529
if err != nil {
return nil, errors.Wrap(err, "get range reader")
}
defer runutil.CloseWithLogOnErr(logger, r, "readIndexRange close range reader")
// Preallocate the buffer with the exact size so we don't waste allocations
// while progressively growing an initial small buffer. The buffer capacity
// is increased by MinRead to avoid extra allocations due to how ReadFrom()
// internally works.
buf := bytes.NewBuffer(make([]byte, 0, length+bytes.MinRead))
if _, err := buf.ReadFrom(r); err != nil {
return nil, errors.Wrap(err, "read range")
}
return buf.Bytes(), nil
}
func (b *bucketBlock) readChunkRange(ctx context.Context, seq int, off, length int64, chunkRanges byteRanges, logger log.Logger) (*[]byte, error) {
if seq < 0 || seq >= len(b.chunkObjs) {
return nil, errors.Errorf("unknown segment file for index %d", seq)
}
// Get a reader for the required range.
reader, err := b.bkt.GetRange(ctx, b.chunkObjs[seq], off, length)
if err != nil {
return nil, errors.Wrap(err, "get range reader")
}
defer runutil.CloseWithLogOnErr(logger, reader, "readChunkRange close range reader")
// Get a buffer from the pool.
chunkBuffer, err := b.chunkPool.Get(chunkRanges.size())
if err != nil {
return nil, errors.Wrap(err, "allocate chunk bytes")
}
*chunkBuffer, err = readByteRanges(reader, *chunkBuffer, chunkRanges)
if err != nil {
return nil, errView on GitHub (pinned to 35b8b99117)