{"record":{"id":"f7f287f50b3eb9bd","repo":"thanos-io/thanos","slug":"invalidargument-f7f287","errorCode":"InvalidArgument","errorMessage":"no matchers specified (excluding external labels)","messagePattern":"no matchers specified \\(excluding external labels\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/store/local.go","lineNumber":142,"sourceCode":"\tif atEOF {\n\t\treturn len(data), data, nil\n\t}\n\t// Incomplete; get more bytes.\n\treturn len(delim), nil, nil\n}\n\n// Series returns all series for a requested time range and label matcher. The returned data may\n// exceed the requested time bounds.\nfunc (s *LocalStore) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesServer) error {\n\tmatch, matchers, err := matchesExternalLabels(r.Matchers, s.extLabels, storecache.NoopMatchersCache)\n\tif err != nil {\n\t\treturn status.Error(codes.InvalidArgument, err.Error())\n\t}\n\tif !match {\n\t\treturn nil\n\t}\n\tif len(matchers) == 0 {\n\t\treturn status.Error(codes.InvalidArgument, errors.New(\"no matchers specified (excluding external labels)\").Error())\n\t}\n\n\tvar chosen []int\n\tfor si, series := range s.series {\n\t\tlbls := labelpb.ZLabelsToPromLabels(series.Labels)\n\t\tvar noMatch bool\n\t\tfor _, m := range matchers {\n\t\t\textValue := lbls.Get(m.Name)\n\t\t\tif extValue == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif !m.Matches(extValue) {\n\t\t\t\tnoMatch = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif noMatch {\n\t\t\tcontinue","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/local.go#L124-L160","documentation":"LocalStore's Series validates that at least one matcher (besides external labels) is provided and returns a gRPC InvalidArgument status error \"no matchers specified (excluding external labels)\" when the list is empty. The Thanos StoreAPI requires matcher-based filtering; a match-all query is not permitted against this store.","triggerScenarios":"Calling the StoreAPI Series RPC with a req whose matchers list, after removing those matching external labels, is empty.","commonSituations":"Clients constructing SeriesRequest with only external-label matchers or an empty matcher list; PrometheusQuerier misconfiguration sending global queries to a store; tooling generating requests programmatically with no matchers.","solutions":["Add at least one label matcher to the SeriesRequest.","Check client-side filtering that strips external-label matchers — don't end up with zero matchers.","If you truly want everything, query with a broad matcher like {__name__!=\"\"} where supported.","Fix tooling that builds the request to always emit >= 1 non-external-label matcher."],"exampleFix":"// before\nreq := &storepb.SeriesRequest{MinTime: t0, MaxTime: t1}\n// after\nreq := &storepb.SeriesRequest{MinTime: t0, MaxTime: t1, Matchers: []labelpb.Matcher{{Type: labelpb.MatchType_EQ, Name: \"__name__\", Value: \"up\"}}}","handlingStrategy":"validation","validationCode":"if len(req.Matchers) == 0 {\n  return status.Error(codes.InvalidArgument, \"no matchers specified\")\n}","typeGuard":null,"tryCatchPattern":"if s, ok := status.FromError(err); ok && s.Code() == codes.InvalidArgument && strings.Contains(s.Message(), \"no matchers\") {\n  // fix request construction before retrying\n}","preventionTips":["Always include at least one non-external-label matcher in SeriesRequest","Centralize request construction so matchers can't be dropped silently","Add client-side tests asserting non-empty matcher lists"],"tags":["go","grpc","validation"],"backgroundTag":"missing-required-argument","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"}