thanos-io/thanos · error

limit must be non-negative

Error message

limit must be non-negative

What it means

A validation guard in parseLimitParam: the limit query parameter parsed successfully as an integer but is negative. Limits of 0 mean 'no limit', so negative values are meaningless and the request is rejected as bad data before the limit is applied.

Solutions

  1. Use a non-negative limit value
  2. Omit the parameter for unlimited results

Example fix

// before
limit := remaining // -1 when budget exhausted
url := fmt.Sprintf("/api/v1/labels?limit=%d", limit)
// after
if limit < 0 { limit = 0 }
url := fmt.Sprintf("/api/v1/labels?limit=%d", limit)
Defensive patterns

Strategy: validation

Validate before calling

function validLimit(s) { const n = parseInt(s, 10); return Number.isInteger(n) && n >= 0; }

Prevention

When it happens

Trigger: Requesting any limit-accepting endpoint with `?limit=-1` (or any negative number).

Common situations: Code computing limits by subtraction (e.g. remaining = budget - used) that went negative; CLI/SDK defaults of -1 meaning 'unlimited' being passed through to Thanos which does not accept -1 as unlimited.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

	}
	if d, err := model.ParseDuration(s); err == nil {
		return time.Duration(d), nil
	}
	return 0, errors.Errorf("cannot parse %q to a valid duration", s)
}

// parseLimitParam returning 0 means no limit is to be applied.
func parseLimitParam(s string) (int, error) {
	if s == "" {
		return 0, nil
	}

	limit, err := strconv.Atoi(s)
	if err != nil {
		return 0, errors.Errorf("cannot parse %q to a valid limit", s)
	}
	if limit < 0 {
		return 0, errors.New("limit must be non-negative")
	}

	return limit, nil
}

// toHintLimit increases the API limit, as returned by parseLimitParam, by 1.
// This allows for emitting warnings when the results are truncated.
func toHintLimit(limit int) int {
	// 0 means no limit and avoid int overflow
	if limit > 0 && limit < math.MaxInt {
		return limit + 1
	}
	return limit
}

// NewMetricMetadataHandler creates handler compatible with HTTP /api/v1/metadata https://prometheus.io/docs/prometheus/latest/querying/api/#querying-metric-metadata
// which uses gRPC Unary Metadata API.
func NewMetricMetadataHandler(client metadata.UnaryClient, enablePartialResponse bool) func(*http.Request) (any, []error, *api.ApiError, func()) {

View on GitHub (pinned to 35b8b99117)