VictoriaMetrics/VictoriaMetrics · error
error when counting unique timeseries: %w
Error message
error when counting unique timeseries: %w
What it means
Wraps an index-iteration failure while counting unique timeseries (TSDB status / cardinality counting). The count is estimated by scanning metricIDs from the index; if the scan errors, the count is abandoned with this annotated error.
Source
Thrown at lib/storage/index_db.go:1301
ts.Seek(kb.B)
for ts.NextItem() {
if loopsPaceLimiter&paceLimiterFastIterationsMask == 0 {
if err := checkSearchDeadlineAndPace(is.deadline); err != nil {
return 0, err
}
}
loopsPaceLimiter++
item := ts.Item
if !bytes.HasPrefix(item, kb.B) {
break
}
// Take into account deleted timeseries too.
// It is OK if series can be counted multiple times in rare cases -
// the returned number is an estimation.
metricIDsLen++
}
if err := ts.Error(); err != nil {
return 0, fmt.Errorf("error when counting unique timeseries: %w", err)
}
return metricIDsLen, nil
}
// GetTSDBStatus returns topN entries for tsdb status for the given tfss, date and focusLabel.
func (db *indexDB) GetTSDBStatus(qt *querytracer.Tracer, tfss []*TagFilters, date uint64, focusLabel string, topN, maxMetrics int, deadline uint64) (*TSDBStatus, error) {
qt = qt.NewChild("collect TSDB status: filters=%s, date=%s, focusLabel=%q, topN=%d, maxMetrics=%d", tfss, dateToString(date), focusLabel, topN, maxMetrics)
defer qt.Done()
if !db.legacyContainsDate(date) {
qt.Printf("indexDB doesn't contain data for the given date: %s", dateToString(date))
return &TSDBStatus{}, nil
}
is := db.getIndexSearch(deadline)
defer db.putIndexSearch(is)
status, err := is.getTSDBStatus(qt, tfss, date, focusLabel, topN, maxMetrics)
if err != nil {View on GitHub (pinned to 5079fb58f1)
Solutions
- Check the wrapped cause (deadline vs I/O vs corruption)
- Increase the search deadline or reduce topN/maxMetrics scope
- Verify index integrity and repair/restore corrupted parts if needed
- Retry during lower load
Defensive patterns
Strategy: try-catch
Validate before calling
// keep TSDB status scope modest before invoking
if topN <= 0 || maxMetrics <= 0 {
return errors.New("invalid status params")
} Try / catch
n, err := db.GetTSDBCountSeries(qt, tfss, date, deadline)
if err != nil {
if strings.Contains(err.Error(), "deadline") {
// retry with larger deadline
} else {
// check storage health
}
return 0
} Prevention
- Schedule heavy cardinality stats off-peak
- Use narrow focusLabel and date ranges
- Keep storage disks healthy and monitored
- Bound maxMetrics to available memory
When it happens
Trigger: Calling GetTSDBCountSeries / TSDB status APIs when the index search over the metricName index errors: I/O failure, corrupted part, or deadline exceeded during heavy scans.
Common situations: Heavy cardinality scans timing out; disk issues on -storageDataPath; concurrent merges slowing scans past deadlines.
Related errors
- error when searching for tag name prefix %q: %w
- error when searching for tag value suffixes for prefix %q: %
- error when counting time series by metric names: %w
- unexpected item len; got %d bytes; want %d bytes
- invalid number of block headers in the previous index block
AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03).
Data as JSON: /api/errors/f85783598d4932aa.
Report an issue: GitHub.