thanos-io/thanos · error

lookup label name

Error message

lookup label name

What it means

LookupLabelsSymbols converts symbolized label pairs back to strings by resolving symbol table references via r.dec.LookupSymbol. Wrapping the name lookup means a symbol referenced by a decoded series does not exist in the block's symbol table — the index bytes reference symbols the reader cannot resolve (wrong block/symbols version, corrupt data, or stale cached series bytes).

Solutions

  1. Invalidate the series cache for the affected block so bytes are re-fetched from the same index version
  2. Verify the block's index (thanos tools bucket verify) and remove/re-upload corrupted blocks
  3. Make sure the index header and symbol table come from the same block instance (never rebuild blocks with reused ULIDs)
  4. Retry the query after store-gateway resyncs its block list to pick up the correct block version
Defensive patterns

Strategy: fallback

Validate before calling

if !r.dec.HasSymbol(ctx, s.name) || !r.dec.HasSymbol(ctx, s.value) {
	// symbol missing from table: re-fetch series bytes from the correct index version
}

Type guard

func symbolsResolvable(dec index.Decoder, s symbolizedLabel) bool { return dec.HasSymbol(s.name) && dec.HasSymbol(s.value) }

Try / catch

if err := r.LookupLabelsSymbols(ctx, symbolized, b); err != nil {
	logger.Warn("symbol lookup failed; refetching series without cache", "err", err)
	invalidateSeriesCache(blockMeta.ULID)
	return retryLookup(ctx, symbolized, b) // retry against fresh index bytes
}

Prevention

When it happens

Trigger: A symbolizedLabel's name reference fails r.dec.LookupSymbol during label-set materialization: cached series bytes belong to a different/older index, symbols cache missing entries, or corrupted index symbol table.

Common situations: Block replaced (ULID reused) causing cached series bytes to reference the wrong symbol table; incomplete index upload missing symbol table sections; querying a block while it is being compacted/deleted.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at pkg/store/bucket.go:3531

	r.block.pendingReaders.Done()

	if r.postings != nil {
		putPostingsSlice(r.postings)
	}
	return nil
}

func (b *blockSeriesClient) CloseSend() error {
	return nil
}

// LookupLabelsSymbols allows populates label set strings from symbolized label set.
func (r *bucketIndexReader) LookupLabelsSymbols(ctx context.Context, symbolized []symbolizedLabel, b *labels.Builder) error {
	b.Reset(labels.EmptyLabels())
	for _, s := range symbolized {
		ln, err := r.dec.LookupSymbol(ctx, s.name)
		if err != nil {
			return errors.Wrap(err, "lookup label name")
		}
		lv, err := r.dec.LookupSymbol(ctx, s.value)
		if err != nil {
			return errors.Wrap(err, "lookup label value")
		}
		b.Set(ln, lv)
	}
	return nil
}

// decodeSeriesForTime decodes a series entry from the given byte slice decoding only chunk metas that are within given min and max time.
// If skipChunks is specified decodeSeriesForTime does not return any chunks, but only labels and only if at least single chunk is within time range.
// decodeSeriesForTime returns false, when there are no series data for given time range.
func decodeSeriesForTime(b []byte, lset *[]symbolizedLabel, chks *[]chunks.Meta, skipChunks bool, selectMint, selectMaxt int64) (ok bool, err error) {
	*lset = (*lset)[:0]
	*chks = (*chks)[:0]

	d := encoding.Decbuf{B: b}

View on GitHub (pinned to 35b8b99117)