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
- Invalidate the series cache for the affected block so bytes are re-fetched from the same index version
- Verify the block's index (thanos tools bucket verify) and remove/re-upload corrupted blocks
- Make sure the index header and symbol table come from the same block instance (never rebuild blocks with reused ULIDs)
- 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
- Invalidate cached series bytes when a block is replaced
- Never rebuild blocks with reused ULIDs
- Validate index symbol table completeness after uploads
- Monitor symbol-lookup failures per block to catch corruption early
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
- label names
- metric label values
- iterate series
- repaired block is invalid
- block with not healthy index found
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)