thanos-io/thanos · error · ApiError

invalid metric metadata limit=

Error message

invalid metric metadata limit='%v'

What it means

The metric metadata handler parses the `limit` query param with ParseInt base 10 bitsize 32; if that fails it reports the raw string as an invalid limit. Note the message prints the parsed (zero) limit, not the input string, because on error `limit` is 0.

Solutions

  1. Pass a plain integer that fits in int32 (0 to 2147483647), e.g. ?limit=100.
  2. Validate with strconv.ParseInt(s, 10, 32) before the request.
  3. Omit the limit parameter to use the server default.

Example fix

// before
GET /api/v1/metadata?limit=99999999999
// after
GET /api/v1/metadata?limit=100
Defensive patterns

Strategy: validation

Validate before calling

function validMetadataLimit(s) {
  if (!/^-?\d+$/.test(s)) return false;
  return BigInt(s) >= -2147483648n && BigInt(s) <= 2147483647n;
}

Prevention

When it happens

Trigger: GET /api/v1/metadata?limit=abc, limit=99999999999 (>int32), or limit=1.5 hitting the QueryAPI metadata handler.

Common situations: Oversized limits exceeding int32 max (2147483647); non-numeric placeholders from UIs; SDKs forwarding raw strings from user config.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

		var (
			t        map[string][]metadatapb.Meta
			warnings annotations.Annotations
			err      error
		)

		req := &metadatapb.MetricMetadataRequest{
			// By default we use -1, which means no limit.
			Limit:                   -1,
			Metric:                  r.URL.Query().Get("metric"),
			PartialResponseStrategy: ps,
		}

		limitStr := r.URL.Query().Get("limit")
		if limitStr != "" {
			limit, err := strconv.ParseInt(limitStr, 10, 32)
			if err != nil {
				return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf("invalid metric metadata limit='%v'", limit)}, func() {}
			}
			req.Limit = int32(limit)
		}

		tracing.DoInSpan(ctx, "retrieve_metadata", func(ctx context.Context) {
			t, warnings, err = client.MetricMetadata(ctx, req)
		})
		if err != nil {
			return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, "retrieving metadata")}, func() {}
		}

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

func (qapi *QueryAPI) tsdbStatus(r *http.Request) (any, []error, *api.ApiError, func()) {
	span, ctx := tracing.StartSpan(r.Context(), "tsdb_statistics_query_request")
	defer span.Finish()

View on GitHub (pinned to 35b8b99117)