thanos-io/thanos · error

got empty chunks

Error message

got empty chunks

What it means

newChunkSeriesIterator requires at least one chunk iterator to construct a chunkSeriesIterator; it is an internal invariant that callers pass a non-empty slice. An empty slice indicates an upstream bug where zero chunk iterators were collected.

Solutions

  1. Report/inspect the calling code path — this signals an internal invariant violation, not user error
  2. Check store responses for empty series data and verify store health
  3. Upgrade Thanos to the latest patch release
  4. File an issue with the query and store logs if reproducible
Defensive patterns

Strategy: try-catch

Try / catch

if err := ss.Err(); err != nil {
    if strings.Contains(err.Error(), "got empty chunks") {
        return storage.EmptySeriesSet(), nil // internal bug; degrade gracefully
    }
    return err
}

Prevention

When it happens

Trigger: Calling newChunkSeriesIterator with a nil/empty []chunkenc.Iterator, which happens only due to an internal defect in how Iterator assembles chunk iterators per series.

Common situations: Encountered as a symptom of a Thanos engine bug, usually alongside concurrent store failures or malformed series responses; rarely caused by user configuration.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/0746e069a6550c1b. Report an issue: GitHub.

Appendix: source

Thrown at pkg/query/iter.go:227

func (errSeriesIterator) AtFloatHistogram(*histogram.FloatHistogram) (int64, *histogram.FloatHistogram) {
	return 0, nil
}
func (errSeriesIterator) AtT() int64    { return 0 }
func (it errSeriesIterator) Err() error { return it.err }

// chunkSeriesIterator implements a series iterator on top
// of a list of time-sorted, non-overlapping chunks.
type chunkSeriesIterator struct {
	chunks  []chunkenc.Iterator
	i       int
	lastVal chunkenc.ValueType

	cur chunkenc.Iterator
}

func newChunkSeriesIterator(cs []chunkenc.Iterator) chunkenc.Iterator {
	if len(cs) == 0 {
		return errSeriesIterator{err: errors.New("got empty chunks")}
	}
	return &chunkSeriesIterator{chunks: cs, cur: cs[0]}
}

func (it *chunkSeriesIterator) Seek(t int64) chunkenc.ValueType {
	// We generally expect the chunks already to be cut down
	// to the range we are interested in. There's not much to be gained from
	// hopping across chunks so we just call next until we reach t.
	for {
		ct := it.AtT()
		if ct >= t {
			return it.lastVal
		}
		it.lastVal = it.Next()
		if it.lastVal == chunkenc.ValNone {
			return chunkenc.ValNone
		}
	}

View on GitHub (pinned to 35b8b99117)