{"record":{"id":"9a026da0ec26bbb6","repo":"thanos-io/thanos","slug":"unknown-9a026d","errorCode":"Unknown","errorMessage":"send tsdb statistics response","messagePattern":"send tsdb statistics response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/status/proxy.go","lineNumber":77,"sourceCode":"\t\t_ = g.Wait()\n\t\tclose(respChan)\n\t}()\n\n\tfor resp := range respChan {\n\t\tstatistics = append(statistics, resp)\n\t}\n\n\tif err := g.Wait(); err != nil {\n\t\tlevel.Error(s.logger).Log(\"err\", err)\n\t\treturn err\n\t}\n\n\tfor _, stat := range statistics {\n\t\ttracing.DoInSpan(srv.Context(), \"send_tsdb_statistics_response\", func(_ context.Context) {\n\t\t\terr = srv.Send(statuspb.NewTSDBStatisticsResponse(stat))\n\t\t})\n\t\tif err != nil {\n\t\t\treturn status.Error(codes.Unknown, errors.Wrap(err, \"send tsdb statistics response\").Error())\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype statsStream struct {\n\tclient  statuspb.StatusClient\n\trequest *statuspb.TSDBStatisticsRequest\n\tchannel chan<- *statuspb.TSDBStatistics\n\tserver  statuspb.Status_TSDBStatisticsServer\n}\n\nfunc (stream *statsStream) receive(ctx context.Context) error {\n\tvar (\n\t\terr         error\n\t\tstatsClient statuspb.Status_TSDBStatisticsClient\n\t)","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/status/proxy.go#L59-L95","documentation":"TSDBStatistics (gRPC server side of the status proxy) streams per-store statistics responses; if srv.Send fails while forwarding a stat, the error is wrapped as 'send tsdb statistics response' and returned with gRPC code Unknown. It means the server could not deliver a statistics message on the stream.","triggerScenarios":"Client disconnects or cancels the context mid-stream; gRPC transport error (broken connection, deadline exceeded) while the server loops `srv.Send(statuspb.NewTSDBStatisticsResponse(stat))` for each stat.","commonSituations":"Client timeout too short for large clusters with many stores; network interruption between client and querier; client process crash during TSDB status fetch; context cancellation in a UI request that timed out.","solutions":["Check client-side logs for the root cause (context deadline exceeded, connection reset) — this error is a symptom of the client/transport failure.","Increase the client request timeout for large TSDB statistics requests.","Verify network connectivity and load balancer idle timeouts between client and server.","Retry the TSDB statistics request; the stream is safe to re-issue."],"exampleFix":"// before\nctx := context.Background()\nresp, err := client.TSDBStatistics(ctx, req)\n// after\nctx, cancel := context.WithTimeout(ctx, 60*time.Second)\ndefer cancel()\nresp, err := client.TSDBStatistics(ctx, req)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"var lastErr error\nfor i := 0; i < 3; i++ {\n    ctx, cancel := context.WithTimeout(ctx, 30*time.Second)\n    err := fetchTSDBStats(ctx)\n    cancel()\n    if err == nil || !isTransportErr(err) { break }\n    lastErr = err\n    time.Sleep(backoff(i))\n}","preventionTips":["Set generous timeouts for TSDB statistics on large clusters.","Keep clients connected until the stream completes.","Monitor LB idle timeouts vs stream duration.","Retry transient transport failures with backoff."],"tags":["grpc","streaming","network","status-api"],"backgroundTag":"broken-pipe","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"}