thanos-io/thanos · warning

results truncated due to limit

Error message

results truncated due to limit

What it means

The labelValues endpoint truncates its result to the limit= parameter and adds a warning (not an error) "results truncated due to limit" when more values exist than the limit allows. The truncated list is still returned (HTTP 200) alongside warnings.AsErrors().

Solutions

  1. Increase the limit parameter (or remove it) to cover all values
  2. Use the match[] parameter to narrow which series' label values are collected
  3. Treat the warning as informational: page through or aggregate client-side

Example fix

// before
GET /api/v1/label/pod/values?limit=10
// after
GET /api/v1/label/pod/values?limit=0  # or match[]=... to scope the query
Defensive patterns

Strategy: type-guard

Validate before calling

// Nothing to pre-validate; inspect the response warnings field:
if resp.Status == "success" && len(resp.Warnings) > 0 {
    // results may be truncated; fetch with a higher limit or match[]
}

Try / catch

if slices.Contains(warnings, "results truncated due to limit") {
    log.Warn("label values truncated; increasing limit")
    // re-issue request with larger limit
}

Prevention

When it happens

Trigger: GET /api/v1/label/<name>/values?limit=N where the label has more than N distinct values; default limits applied by clients/proxies.

Common situations: High-cardinality labels (pod names, trace IDs) with thousands of values; dashboards setting a small limit for performance.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at pkg/api/query/v1.go:1164

		vals = make([]string, 0, len(labelValuesSet))
		for val := range labelValuesSet {
			vals = append(vals, val)
		}
		sort.Strings(vals)
	} else {
		vals, warnings, err = q.LabelValues(ctx, name, hints)
		if err != nil {
			return nil, nil, &api.ApiError{Typ: api.ErrorExec, Err: err}, func() {}
		}
	}

	if vals == nil {
		vals = make([]string, 0)
	}

	if limit > 0 && len(vals) > limit {
		vals = vals[:limit]
		warnings = warnings.Add(errors.New("results truncated due to limit"))
	}

	return vals, warnings.AsErrors(), nil, func() {}
}

func (qapi *QueryAPI) series(r *http.Request) (any, []error, *api.ApiError, func()) {
	if err := r.ParseForm(); err != nil {
		return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, "parse form")}, func() {}
	}

	if len(r.Form[MatcherParam]) == 0 {
		return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.New("no match[] parameter provided")}, func() {}
	}

	start, end, err := parseMetadataTimeRange(r, qapi.defaultMetadataTimeRange)
	if err != nil {
		return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: err}, func() {}
	}

View on GitHub (pinned to 35b8b99117)