thanos-io/thanos · error

no matchers specified (excluding selector labels)

Error message

no matchers specified (excluding selector labels)

What it means

The proxy Store's Series gRPC handler requires at least one matcher beyond any automatically added selector (external label) matchers. If len(matchers)==0, it returns an InvalidArgument gRPC status with the message "no matchers specified (excluding selector labels)". A query that selects everything (e.g. empty matcher set) is rejected instead of fanning out to all stores.

Solutions

  1. Add at least one real label matcher to the query (e.g. {__name__="up"} instead of {})
  2. Review --selector.relabel-config / selector labels to understand which matchers are stripped before this check
  3. If calling the gRPC API programmatically, populate req.Matchers before sending

Example fix

// before: only selector labels remain, matchers empty
req := &storepb.SeriesRequest{MinTime: t0, MaxTime: t1}
// after: include a concrete matcher
req.Matchers = []labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "__name__", "http_requests_total")}
Defensive patterns

Strategy: validation

Validate before calling

if len(req.Matchers) == 0 {
    return status.Error(codes.InvalidArgument, "no matchers specified (excluding selector labels)")
}

Try / catch

_, err := storeClient.Series(ctx, req)
if status.Code(err) == codes.InvalidArgument {
    // add concrete label matchers (e.g. __name__) before retrying
}

Prevention

When it happens

Trigger: Calling the storepb Store Series API (or the PromQL engine resolving to it) with an empty matcher list, e.g. promql query `{}` with selectorLabels stripped out, or a client constructing the SeriesRequest without matchers.

Common situations: Typo in a PromQL query leaving only the external-label selector (`{cluster="x"}` when cluster is the selector label); programmatic storepb.SeriesRequest built with nil matchers; regression where selector labels were miscounted.

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/076e8e116ac2de0a. Report an issue: GitHub.

Appendix: source

Thrown at pkg/store/proxy.go:300

	srv := newBatchableServer(seriesSrv, int(originalRequest.ResponseBatchSize))

	// TODO(bwplotka): This should be part of request logger, otherwise it does not make much sense. Also, could be
	// triggered by tracing span to reduce cognitive load.
	reqLogger := log.With(s.logger, "component", "proxy")
	if s.debugLogging {
		reqLogger = log.With(reqLogger, "request", originalRequest.String())
	}

	match, matchers, err := matchesExternalLabels(originalRequest.Matchers, s.selectorLabels, s.matcherCache)
	if err != nil {
		return status.Error(codes.InvalidArgument, err.Error())
	}
	if !match {
		return nil
	}

	if len(matchers) == 0 {
		return status.Error(codes.InvalidArgument, errors.New("no matchers specified (excluding selector labels)").Error())
	}

	// We may arrive here either via the promql engine
	// or as a result of a grpc call in layered queries
	ctx := srv.Context()
	tenant, foundTenant := tenancy.GetTenantFromGRPCMetadata(ctx)
	if !foundTenant {
		if ctx.Value(tenancy.TenantKey) != nil {
			tenant = ctx.Value(tenancy.TenantKey).(string)
		}
	}

	ctx = metadata.AppendToOutgoingContext(ctx, tenancy.DefaultTenantHeader, tenant)
	level.Debug(s.logger).Log("msg", "Tenant info in Series()", "tenant", tenant)

	// There are no stores registered at all and partial results are disabled, return an error.
	stores := s.stores()
	if len(stores) == 0 && (originalRequest.PartialResponseDisabled || originalRequest.PartialResponseStrategy == storepb.PartialResponseStrategy_ABORT) {

View on GitHub (pinned to 35b8b99117)