thanos-io/thanos · error

label names

Error message

label names

What it means

After reading postings, GatherIndexHealthStats calls r.LabelNames(ctx) to count label names in the index. If the index's label-name symbol/postings lookup fails, the error is wrapped as "label names". It indicates the index symbol or postings tables are unreadable.

Solutions

  1. Re-download or restore the block from its source (object storage/backup)
  2. Confirm with VerifyIndex / index verification tooling that the symbols table is corrupt
  3. Increase context timeout when validating large blocks
  4. Discard the corrupt block so Thanos re-fetches it

Example fix

// before
stats, err := block.GatherIndexHealthStats(ctx, bdir) // label names: symbols decode error
// after
ctx, cancel := context.WithTimeout(ctx, 10*time.Minute)
defer cancel()
stats, err := block.GatherIndexHealthStats(ctx, bdir)
if err != nil { logger.Log("msg", "index health check failed", "err", err) }
Defensive patterns

Strategy: try-catch

Validate before calling

if err := block.VerifyIndex(ctx, bdir, 1); err != nil {
    return fmt.Errorf("skip unhealthy block %s: %w", bdir, err)
}

Try / catch

stats, err := block.GatherIndexHealthStats(ctx, bdir)
if err != nil && strings.Contains(err.Error(), "label names") {
    return fmt.Errorf("block %s symbols table corrupt: %w", bdir, err)
}

Prevention

When it happens

Trigger: GatherIndexHealthStats/VerifyIndex on a block whose index file's label-name postings entries reference missing symbols or are truncated, or whose ctx is cancelled during LabelNames.

Common situations: Corrupt block uploads, partially downloaded index files, bit-rot on local disks, or scanning many blocks with tight context deadlines.

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/bd8cb0cbb7e992b9. Report an issue: GitHub.

Appendix: source

Thrown at pkg/block/index.go:247

	}
	var (
		lset     labels.Labels
		prevLset labels.Labels
		builder  labels.ScratchBuilder

		chks []chunks.Meta

		seriesLifeDuration                          = newMinMaxSumInt64()
		seriesLifeDurationWithoutSingleSampleSeries = newMinMaxSumInt64()
		seriesChunks                                = newMinMaxSumInt64()
		chunkDuration                               = newMinMaxSumInt64()
		chunkSize                                   = newMinMaxSumInt64()
		seriesSize                                  = newMinMaxSumInt64()
	)

	lnames, err := r.LabelNames(ctx)
	if err != nil {
		return stats, errors.Wrap(err, "label names")
	}
	stats.LabelNamesCount = int64(len(lnames))

	lvals, err := r.LabelValues(ctx, "__name__", nil)
	if err != nil {
		return stats, errors.Wrap(err, "metric label values")
	}
	stats.MetricLabelValuesCount = int64(len(lvals))

	// As of version two all series entries are 16 byte padded. All references
	// we get have to account for that to get the correct offset.
	offsetMultiplier := 1
	version := r.Version()
	if version >= 2 {
		offsetMultiplier = 16
	}

	// Per series.

View on GitHub (pinned to 35b8b99117)