{"record":{"id":"432a82e991b310ef","repo":"thanos-io/thanos","slug":"res-getwarning-432a82","errorCode":null,"errorMessage":"res.GetWarning()","messagePattern":"res\\.GetWarning\\(\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/status/status.go","lineNumber":82,"sourceCode":"\n\treturn tsdbStatistics, srv.warnings, nil\n}\n\ntype tsdbStatisticsServer struct {\n\t// This field just exist to pseudo-implement the unused methods of the interface.\n\tstatuspb.Status_TSDBStatisticsServer\n\tctx context.Context\n\n\tmtx            sync.Mutex\n\twarnings       annotations.Annotations\n\ttsdbStatistics map[string][]*statuspb.TSDBStatisticsEntry\n}\n\nfunc (srv *tsdbStatisticsServer) Send(res *statuspb.TSDBStatisticsResponse) error {\n\tif res.GetWarning() != \"\" {\n\t\tsrv.mtx.Lock()\n\t\tdefer srv.mtx.Unlock()\n\t\tsrv.warnings.Add(errors.New(res.GetWarning()))\n\t\treturn nil\n\t}\n\n\tstats := res.GetStatistics()\n\tif stats == nil {\n\t\treturn errors.New(\"no tsdb statistics\")\n\t}\n\n\tsrv.mtx.Lock()\n\tdefer srv.mtx.Unlock()\n\tfor tenant, tenantStats := range stats.Statistics {\n\t\tif _, found := srv.tsdbStatistics[tenant]; !found {\n\t\t\tsrv.tsdbStatistics[tenant] = nil\n\t\t}\n\t\tsrv.tsdbStatistics[tenant] = append(srv.tsdbStatistics[tenant], tenantStats)\n\t}\n\n\treturn nil","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/status/status.go#L64-L100","documentation":"tsdbStatisticsServer.Send processes responses coming back from the proxy. A response carrying a non-empty warning is appended to srv.warnings and handled gracefully, so the message 'res.GetWarning()' flags the branch where a warning was received (and, if stats are nil and no warning present, 'no tsdb statistics' is returned). It signals an upstream store reported a problem for its statistics.","triggerScenarios":"During TSDBStatistics aggregation, a store member returns a WarningTSDBStatisticsResponse (e.g. that store failed to compute stats), so Send() takes the `res.GetWarning() != \"\"` branch and records the warning.","commonSituations":"A store node returning errors under WARNINGS strategy (down disk, TSDB not ready, store starting up); partial results surfaced to the Thanos UI as warnings banner.","solutions":["Read the recorded warning text to identify which store failed and why.","Fix or restart the offending store node.","If strictness is required, use ABORT strategy to fail instead of accumulating warnings.","Check store logs around the same timestamp for the underlying TSDB error."],"exampleFix":"// before\n// warnings silently accumulate, request 'succeeds' with partial data\nfor _, w := range srv.warnings { logger.Warn(w) }\n// after\nif srv.warnings.Len() > 0 {\n    return nil, nil, fmt.Errorf(\"tsdb statistics incomplete: %v\", srv.warnings)\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isStatsWarning(res *statuspb.TSDBStatisticsResponse) (string, bool) {\n    if res == nil {\n        return \"\", false\n    }\n    w := res.GetWarning()\n    return w, w != \"\"\n}","tryCatchPattern":"if err := call(ctx); err != nil {\n    var warnMsg string\n    if strings.Contains(err.Error(), \"res.GetWarning\") || strings.Contains(err.Error(), \"no tsdb statistics\") {\n        warnMsg = err.Error()\n        logger.Warn(\"partial tsdb statistics\", \"detail\", warnMsg)\n        return nil\n    }\n    return err\n}","preventionTips":["Check and display srv.warnings after aggregation.","Restart stores reporting warnings before relying on stats.","Choose ABORT vs WARNINGS strategy based on how much you trust partial data.","Track warning rates per store as a health signal."],"tags":["grpc","warnings","tsdb","partial-results"],"backgroundTag":"unexpected-response-shape","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"}