diff --git a/pkg/querier/ingester_querier.go b/pkg/querier/ingester_querier.go index e99fe6882df4..c18ca7793066 100644 --- a/pkg/querier/ingester_querier.go +++ b/pkg/querier/ingester_querier.go @@ -380,6 +380,10 @@ func (q *IngesterQuerier) DetectedLabel(ctx context.Context, req *logproto.Detec "response", resp) } + if thisIngester == nil { + continue + } + for label, thisIngesterValues := range thisIngester.Labels { var combinedValues []string allIngesterValues, isLabelPresent := labelMap[label] diff --git a/pkg/querier/querier.go b/pkg/querier/querier.go index 12429e68a3e0..bafbe334cdf7 100644 --- a/pkg/querier/querier.go +++ b/pkg/querier/querier.go @@ -985,14 +985,14 @@ func (q *SingleTenantQuerier) DetectedLabels(ctx context.Context, req *logproto. }, nil } - // append static labels before so they are in sorted order - for l := range staticLabels { - if values, present := ingesterLabels.Labels[l]; present { - detectedLabels = append(detectedLabels, &logproto.DetectedLabel{Label: l, Cardinality: uint64(len(values.Values))}) + if ingesterLabels != nil { + // append static labels before so they are in sorted order + for l := range staticLabels { + if values, present := ingesterLabels.Labels[l]; present { + detectedLabels = append(detectedLabels, &logproto.DetectedLabel{Label: l, Cardinality: uint64(len(values.Values))}) + } } - } - if ingesterLabels != nil { for label, values := range ingesterLabels.Labels { if q.isLabelRelevant(label, values.Values, staticLabels) { combinedValues := values.Values diff --git a/pkg/querier/querier_test.go b/pkg/querier/querier_test.go index 2dfd3d897431..66370c34460b 100644 --- a/pkg/querier/querier_test.go +++ b/pkg/querier/querier_test.go @@ -1714,4 +1714,31 @@ func TestQuerier_DetectedLabels(t *testing.T) { assert.Contains(t, detectedLabels, &logproto.DetectedLabel{Label: "pod", Cardinality: 4}) assert.Contains(t, detectedLabels, &logproto.DetectedLabel{Label: "namespace", Cardinality: 60}) }) + + t.Run("no panics with ingester response is nil", func(t *testing.T) { + ingesterClient := newQuerierClientMock() + storeClient := newStoreMock() + + ingesterClient.On("GetDetectedLabels", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil, nil) + storeClient.On("LabelNamesForMetricName", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]string{}, nil) + request := logproto.DetectedLabelsRequest{ + Start: &now, + End: &now, + Query: "", + } + + querier, err := newQuerier( + conf, + mockIngesterClientConfig(), + newIngesterClientMockFactory(ingesterClient), + mockReadRingWithOneActiveIngester(), + &mockDeleteGettter{}, + storeClient, limits) + require.NoError(t, err) + + _, err = querier.DetectedLabels(ctx, &request) + require.NoError(t, err) + }) }