{"record":{"id":"124a20a5fa413a43","repo":"thanos-io/thanos","slug":"receiving-tsdb-statistics-from-status-client-v","errorCode":null,"errorMessage":"receiving tsdb statistics from status client %v","messagePattern":"receiving tsdb statistics from status client (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/status/proxy.go","lineNumber":123,"sourceCode":"\t\t\treturn err\n\t\t}\n\n\t\tif serr := stream.server.Send(statuspb.NewWarningTSDBStatisticsResponse(err)); serr != nil {\n\t\t\treturn serr\n\t\t}\n\n\t\t// Not an error if response strategy is warning.\n\t\treturn nil\n\t}\n\n\tfor {\n\t\tresp, err := statsClient.Recv()\n\t\tif err == io.EOF {\n\t\t\treturn nil\n\t\t}\n\n\t\tif err != nil {\n\t\t\terr = errors.Wrapf(err, \"receiving tsdb statistics from status client %v\", stream.client)\n\n\t\t\tif stream.request.PartialResponseStrategy == storepb.PartialResponseStrategy_ABORT {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif err := stream.server.Send(statuspb.NewWarningTSDBStatisticsResponse(err)); err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"sending tsdb statistics error to server %v\", stream.server)\n\t\t\t}\n\n\t\t\t// Not an error if response strategy is warning.\n\t\t\treturn nil\n\t\t}\n\n\t\tif w := resp.GetWarning(); w != \"\" {\n\t\t\tif err := stream.server.Send(statuspb.NewWarningTSDBStatisticsResponse(errors.New(w))); err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"sending tsdb statistics warning to server %v\", stream.server)\n\t\t\t}\n\t\t\tcontinue","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/status/proxy.go#L105-L141","documentation":"While consuming the store's statistics stream (`statsClient.Recv()`), any error other than io.EOF is wrapped as 'receiving tsdb statistics from status client %v'. It indicates the upstream stream broke mid-transfer rather than failing to start.","triggerScenarios":"Calling receive() on the proxy stream when the store's gRPC connection drops, the server cancels the stream, or a transport/deadline error occurs after the initial TSDBStatistics call succeeded.","commonSituations":"Store crashes mid-response; connection reset by load balancer idle timeout on long streams; context cancellation by the downstream client; TLS handshake re-negotiation failure.","solutions":["Retry the statistics request; transient stream drops are common.","Check the store node's logs and health at the time of the failure.","Adjust proxy/LB idle timeouts to exceed the expected streaming duration.","Use PartialResponseStrategy WARNINGS to surface this as a warning instead of failing the request."],"exampleFix":"// before\nif err != nil { return err } // aborts whole request on ABORT strategy\n// after\nif err != nil {\n    logger.Warn(\"tsdb statistics stream from store broke, results partial\", \"err\", err)\n    return nil // with WARNINGS strategy\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := streamStats(ctx)\nif err != nil && strings.Contains(err.Error(), \"receiving tsdb statistics\") {\n    // transient mid-stream drop: retry whole request\n    return retryWithBackoff(streamStats, ctx)\n}","preventionTips":["Keep store nodes healthy; monitor restarts.","Set stream timeouts above worst-case transfer time.","Tune LB idle timeouts for long gRPC streams.","Use WARNINGS strategy to degrade gracefully."],"tags":["grpc","streaming","proxy","network"],"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"}