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
- Use a non-negative limit value
- 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
- Clamp computed limits with Math.max(0, n).
- Do not use -1 as an 'unlimited' sentinel with Thanos; omit the param instead.
- Test negative-value paths in client code.
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
- cannot parse to a valid limit
- invalid metric metadata limit=
- cannot parse to a valid duration. It overflows int64
- cannot parse to a valid duration
- unsupported format for label
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)