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

  1. Check the wrapped cause (deadline vs I/O vs corruption)
  2. Increase the search deadline or reduce topN/maxMetrics scope
  3. Verify index integrity and repair/restore corrupted parts if needed
  4. 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

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


AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03). Data as JSON: /api/errors/f85783598d4932aa. Report an issue: GitHub.