{"record":{"id":"b51e1afbb3ba1e29","repo":"thanos-io/thanos","slug":"invalid-metric-metadata-limit-v","errorCode":null,"errorMessage":"invalid metric metadata limit='%v'","messagePattern":"invalid metric metadata limit='(.+?)'","errorType":"http","errorClass":"ApiError","httpStatus":400,"severity":"error","filePath":"pkg/api/query/v1.go","lineNumber":1672,"sourceCode":"\n\t\tvar (\n\t\t\tt        map[string][]metadatapb.Meta\n\t\t\twarnings annotations.Annotations\n\t\t\terr      error\n\t\t)\n\n\t\treq := &metadatapb.MetricMetadataRequest{\n\t\t\t// By default we use -1, which means no limit.\n\t\t\tLimit:                   -1,\n\t\t\tMetric:                  r.URL.Query().Get(\"metric\"),\n\t\t\tPartialResponseStrategy: ps,\n\t\t}\n\n\t\tlimitStr := r.URL.Query().Get(\"limit\")\n\t\tif limitStr != \"\" {\n\t\t\tlimit, err := strconv.ParseInt(limitStr, 10, 32)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf(\"invalid metric metadata limit='%v'\", limit)}, func() {}\n\t\t\t}\n\t\t\treq.Limit = int32(limit)\n\t\t}\n\n\t\ttracing.DoInSpan(ctx, \"retrieve_metadata\", func(ctx context.Context) {\n\t\t\tt, warnings, err = client.MetricMetadata(ctx, req)\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, \"retrieving metadata\")}, func() {}\n\t\t}\n\n\t\treturn t, warnings.AsErrors(), nil, func() {}\n\t}\n}\n\nfunc (qapi *QueryAPI) tsdbStatus(r *http.Request) (any, []error, *api.ApiError, func()) {\n\tspan, ctx := tracing.StartSpan(r.Context(), \"tsdb_statistics_query_request\")\n\tdefer span.Finish()","sourceCodeStart":1654,"sourceCodeEnd":1690,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/api/query/v1.go#L1654-L1690","documentation":"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.","triggerScenarios":"GET /api/v1/metadata?limit=abc, limit=99999999999 (>int32), or limit=1.5 hitting the QueryAPI metadata handler.","commonSituations":"Oversized limits exceeding int32 max (2147483647); non-numeric placeholders from UIs; SDKs forwarding raw strings from user config.","solutions":["Pass a plain integer that fits in int32 (0 to 2147483647), e.g. ?limit=100.","Validate with strconv.ParseInt(s, 10, 32) before the request.","Omit the limit parameter to use the server default."],"exampleFix":"// before\nGET /api/v1/metadata?limit=99999999999\n// after\nGET /api/v1/metadata?limit=100","handlingStrategy":"validation","validationCode":"function validMetadataLimit(s) {\n  if (!/^-?\\d+$/.test(s)) return false;\n  return BigInt(s) >= -2147483648n && BigInt(s) <= 2147483647n;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep limits within int32 range (max 2147483647).","Prefer modest limits (100–10000) — metadata responses are large.","Validate all query params against the endpoint's expected types in the client SDK."],"tags":["metadata","limit","bad-request","query-api"],"backgroundTag":"invalid-query-parameter","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}