{"record":{"id":"bfb3062f50806176","repo":"thanos-io/thanos","slug":"proxy-targets","errorCode":null,"errorMessage":"proxy Targets","messagePattern":"proxy Targets","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/targets/targets.go","lineNumber":57,"sourceCode":"\tc := &GRPCClient{\n\t\tproxy:         ts,\n\t\treplicaLabels: map[string]struct{}{},\n\t}\n\n\tfor _, label := range replicaLabels {\n\t\tc.replicaLabels[label] = struct{}{}\n\t}\n\treturn c\n}\n\nfunc (rr *GRPCClient) Targets(ctx context.Context, req *targetspb.TargetsRequest) (*targetspb.TargetDiscovery, annotations.Annotations, error) {\n\tresp := &targetsServer{ctx: ctx, targets: &targetspb.TargetDiscovery{\n\t\tActiveTargets:  make([]*targetspb.ActiveTarget, 0),\n\t\tDroppedTargets: make([]*targetspb.DroppedTarget, 0),\n\t}}\n\n\tif err := rr.proxy.Targets(req, resp); err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"proxy Targets\")\n\t}\n\n\tresp.targets = dedupTargets(resp.targets, rr.replicaLabels)\n\n\treturn resp.targets, resp.warnings, nil\n}\n\n// dedupTargets re-sorts the set so that the same target with different replica\n// labels are coming right after each other.\nfunc dedupTargets(targets *targetspb.TargetDiscovery, replicaLabels map[string]struct{}) *targetspb.TargetDiscovery {\n\tif targets == nil {\n\t\treturn nil\n\t}\n\n\ttargets.ActiveTargets = dedupActiveTargets(targets.ActiveTargets, replicaLabels)\n\ttargets.DroppedTargets = dedupDroppedTargets(targets.DroppedTargets, replicaLabels)\n\n\treturn targets","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/targets/targets.go#L39-L75","documentation":"This error wraps any failure produced by rr.proxy.Targets() during a proxied TargetDiscovery request through a Rules/targets replica-aware proxy. It means the fan-out to underlying TargetsAPI clients (gathering active/dropped targets) failed, e.g. no clients or all replicas returned errors.","triggerScenarios":"GRPCProxy.Targets (via TargetsServer in pkg/targets/targets.go:57) returns a non-nil error from proxying the Targets request to backend store/targets endpoints.","commonSituations":"No healthy TargetsAPI endpoints registered (all sidecars down); all replicas failed so proxy returns error; context deadline during fan-out; querier cannot discover store endpoints via mDNS/DNS.","solutions":["Check the wrapped cause: if 'no such subscription' or 'no endpoints', no targets providers are registered — verify store/sidecar discovery.","Ensure sidecars/store gateways are up and registered via the same mDNS/DNS service discovery as the querier.","Use PartialResponseStrategy_WARNING to tolerate some endpoint failures.","Check network connectivity and gRPC health of all listed endpoints (thanos tools bucket verify / query UI store page)."],"exampleFix":"// before\nclient, err := proxy.Targets(ctx, req)\n// after: tolerate partial failures\nreq.PartialResponseStrategy = storepb.PartialResponseStrategy_WARNING\nclient, err := proxy.Targets(ctx, req)","handlingStrategy":"fallback","validationCode":"// Verify at least one targets provider is registered before fan-out\nif len(endpoints) == 0 { return nil, errors.New(\"no targets endpoints registered\") }","typeGuard":null,"tryCatchPattern":"resp, err := proxy.Targets(ctx, req)\nif err != nil {\n    log.Warn(\"targets proxy failed, returning empty\", zap.Error(err))\n    return &targetspb.TargetDiscovery{}, nil\n}","preventionTips":["Keep sidecar/store discovery (DNS/mDNS) healthy","Use WARNING partial response strategy for UI queries","Alert on registered endpoint count dropping to zero"],"tags":["grpc","proxy","fanout","thanos-targets"],"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"}