{"record":{"id":"de6806ce058bd54e","repo":"thanos-io/thanos","slug":"fetching-targets-from-targets-client-v","errorCode":null,"errorMessage":"fetching targets from targets client %v","messagePattern":"fetching targets from targets client (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/targets/proxy.go","lineNumber":93,"sourceCode":"\t\tif err := srv.Send(targetspb.NewTargetsResponse(t)); err != nil {\n\t\t\treturn status.Error(codes.Unknown, errors.Wrap(err, \"send targets response\").Error())\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype targetsStream struct {\n\tclient  targetspb.TargetsClient\n\trequest *targetspb.TargetsRequest\n\tchannel chan<- *targetspb.TargetDiscovery\n\tserver  targetspb.Targets_TargetsServer\n}\n\nfunc (stream *targetsStream) receive(ctx context.Context) error {\n\ttargets, err := stream.client.Targets(ctx, stream.request)\n\tif err != nil {\n\t\terr = errors.Wrapf(err, \"fetching targets from targets client %v\", stream.client)\n\n\t\tif stream.request.PartialResponseStrategy == storepb.PartialResponseStrategy_ABORT {\n\t\t\treturn err\n\t\t}\n\n\t\tif serr := stream.server.Send(targetspb.NewWarningTargetsResponse(err)); serr != nil {\n\t\t\treturn serr\n\t\t}\n\t\t// Not an error if response strategy is warning.\n\t\treturn nil\n\t}\n\n\tfor {\n\t\ttarget, err := targets.Recv()\n\t\tif err == io.EOF {\n\t\t\treturn nil\n\t\t}\n","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/targets/proxy.go#L75-L111","documentation":"The targetsStream.receive fetches targets from the upstream Targets client and wraps any RPC failure with 'fetching targets from targets client %v'. Under PartialResponseStrategy_ABORT it returns the wrapped error; otherwise it forwards the wrapped error as a warning response to the downstream server and only fails if sending that warning also fails.","triggerScenarios":"stream.client.Targets(ctx, request) returns an error during receive — upstream targets API unavailable, invalid request rejected by upstream, context cancellation, or timeout.","commonSituations":"Targets discovery backend (e.g. a store with targets API) down or unreachable, wrong address configured for the targets client, transient network errors in meshes where partial-response strategy tolerates failures.","solutions":["Check connectivity/auth to the upstream targets endpoint referenced by stream.client","Inspect the wrapped cause to see the upstream gRPC status","If using ABORT strategy, add retry with backoff for transient upstream errors","If partial-response is acceptable, keep the current strategy and monitor the warning responses instead of failing"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := stream.receive(ctx); err != nil { if strategy == ABORT { return err } /* warning already forwarded; degrade gracefully */ }","preventionTips":["Choose PartialResponseStrategy wisely: ABORT for correctness-critical paths, warning-tolerant for HA queries","Health-check the upstream targets client endpoint before fan-out","Add retries with backoff for transient upstream Target RPC failures"],"tags":["grpc","targets","proxy","upstream"],"backgroundTag":"upstream-api-error","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"}