thanos-io/thanos · error · ApiError

no match[] parameter provided

Error message

no match[] parameter provided

What it means

The series endpoint requires at least one match[] parameter to select series; if r.Form[MatcherParam] is empty it returns ErrorBadData (HTTP 400) "no match[] parameter provided". Without matchers the querier cannot determine which series to return.

Solutions

  1. Add at least one match[] parameter, e.g. ?match[]=up
  2. If a dashboard variable may be empty, substitute a catch-all matcher like {__name__!=""}
  3. Verify URL encoding so match[] actually reaches the server

Example fix

// before
GET /api/v1/series
// after
GET /api/v1/series?match[]=up
Defensive patterns

Strategy: validation

Validate before calling

if len(matchers) == 0 {
    matchers = []string{`{__name__!=""}`} // or return an error to the user first
}

Prevention

When it happens

Trigger: GET/POST /api/v1/series without any match[] form value, or with match[] present but an empty string so it doesn't register in r.Form.

Common situations: Clients forgetting the mandatory parameter; URL encoding issues dropping the value; dashboards with unset template variables producing empty match[].

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

	if vals == nil {
		vals = make([]string, 0)
	}

	if limit > 0 && len(vals) > limit {
		vals = vals[:limit]
		warnings = warnings.Add(errors.New("results truncated due to limit"))
	}

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

func (qapi *QueryAPI) series(r *http.Request) (any, []error, *api.ApiError, func()) {
	if err := r.ParseForm(); err != nil {
		return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Wrap(err, "parse form")}, func() {}
	}

	if len(r.Form[MatcherParam]) == 0 {
		return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.New("no match[] parameter provided")}, func() {}
	}

	start, end, err := parseMetadataTimeRange(r, qapi.defaultMetadataTimeRange)
	if err != nil {
		return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: err}, func() {}
	}

	matcherSets, ctx, err := tenancy.RewriteLabelMatchers(r.Context(), r, qapi.tenantHeader, qapi.defaultTenant, qapi.tenantCertField, qapi.enforceTenancy, qapi.tenantLabel, r.Form[MatcherParam])
	if err != nil {
		apiErr := &api.ApiError{Typ: api.ErrorBadData, Err: err}
		return nil, nil, apiErr, func() {}
	}

	enableDedup, apiErr := qapi.parseEnableDedupParam(r)
	if apiErr != nil {
		return nil, nil, apiErr, func() {}
	}

View on GitHub (pinned to 35b8b99117)