thanos-io/thanos · error · ApiError
limit overflows int32
Error message
limit %d overflows int32
What it means
A range guard in the query API: the requested limit fits an int64 but exceeds math.MaxInt32, which is the widest limit the store API can carry in its protobuf fields. The request is rejected as bad data rather than silently truncating the limit.
Solutions
- Use a limit <= 2147483647
- Paginate queries instead of one huge limit
Example fix
// before GET /api/v1/tsdb/status?limit=3000000000 // after GET /api/v1/tsdb/status?limit=1000000
Defensive patterns
Strategy: validation
Validate before calling
function validTsdbLimit(n) { return Number.isInteger(n) && n >= 0 && n <= 2147483647; } Prevention
- Cap limits at math.MaxInt32 (2147483647).
- Use a sane finite limit (e.g. 1e6) rather than a huge 'unlimited' value.
- Reuse one client constant for the max allowed limit.
When it happens
Trigger: GET /api/v1/tsdb/status?limit=3000000000 (any value > 2147483647) reaching the tsdbStatus handler.
Common situations: Users attempting 'practically unlimited' limits with huge numbers; script-generated limits from config files; confusion with int64-range limits accepted by other endpoints.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- cannot parse to a valid duration. It overflows int64
- cannot parse to a valid limit
- limit must be non-negative
- invalid metric metadata limit=
- retrieving tsdb statistics
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/baf77586f7fbf2a8.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/api/query/v1.go:1748
// Append tenant matcher when tenancy is enabled.
var tenant string
if qapi.enforceTenancy {
tenant, err = tenancy.GetTenantFromHTTP(r, qapi.tenantHeader, qapi.defaultTenant, qapi.tenantCertField)
if err != nil {
return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: err}, func() {}
}
if tenant != "" {
matchers = append(matchers, storepb.LabelMatcher{
Type: storepb.LabelMatcher_EQ,
Name: qapi.tenantLabel,
Value: tenant,
})
}
}
if limit > math.MaxInt32 {
return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf("limit %d overflows int32", limit)}, func() {}
}
req := &statuspb.TSDBStatisticsRequest{
Matchers: matchers,
Limit: int32(limit),
PartialResponseStrategy: ps,
}
var stats map[string]*statuspb.TSDBStatisticsEntry
tracing.DoInSpan(ctx, "retrieve_tsdb_statistics", func(ctx context.Context) {
stats, warnings, err = qapi.status.TSDBStatistics(ctx, req)
})
if err != nil {
return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, "retrieving tsdb statistics")}, func() {}
}
if tenant != "" {
if stats[tenant] == nil {View on GitHub (pinned to 35b8b99117)