{"record":{"id":"d8e23f146bea4e62","repo":"thanos-io/thanos","slug":"read-query-range-response","errorCode":null,"errorMessage":"read query range response","messagePattern":"read query range response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/promclient/promclient.go","lineNumber":561,"sourceCode":"\tparams.Add(\"step\", strconv.FormatInt(step, 10))\n\tif !opts.DoNotAddThanosParams {\n\t\tif err := opts.AddTo(params); err != nil {\n\t\t\treturn nil, nil, nil, errors.Wrap(err, \"add thanos opts query params\")\n\t\t}\n\t}\n\n\tu := *base\n\tu.Path = path.Join(u.Path, \"/api/v1/query_range\")\n\tu.RawQuery = params.Encode()\n\n\tlevel.Debug(c.logger).Log(\"msg\", \"range query\", \"url\", u.String())\n\n\tspan, ctx := tracing.StartSpan(ctx, \"/prom_query_range HTTP[client]\")\n\tdefer span.Finish()\n\n\tbody, _, err := c.req2xx(ctx, &u, http.MethodGet, opts.HTTPHeaders)\n\tif err != nil {\n\t\treturn nil, nil, nil, errors.Wrap(err, \"read query range response\")\n\t}\n\n\t// Decode only ResultType and load Result only as RawJson since we don't know\n\t// structure of the Result yet.\n\tvar m struct {\n\t\tData struct {\n\t\t\tResultType  string          `json:\"resultType\"`\n\t\t\tResult      json.RawMessage `json:\"result\"`\n\t\t\tExplanation *Explanation    `json:\"explanation,omitempty\"`\n\t\t} `json:\"data\"`\n\n\t\tError     string `json:\"error,omitempty\"`\n\t\tErrorType string `json:\"errorType,omitempty\"`\n\t\t// Extra fields supported by Thanos Querier.\n\t\tWarnings []string `json:\"warnings\"`\n\t}\n\n\tif err = json.Unmarshal(body, &m); err != nil {","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/promclient/promclient.go#L543-L579","documentation":"QueryRange issues a GET to the /api/v1/query_range endpoint through c.req2xx, which requires a 2xx response. If the HTTP request fails at the transport level or the server returns a non-2xx status, the library wraps the error with 'read query range response'. This is the network/HTTP failure path for range queries.","triggerScenarios":"Calling QueryRange (via Exec) when the Prometheus endpoint is unreachable, the connection is refused or times out, TLS fails, or the server responds with a 4xx/5xx status (overloaded, bad request, auth failure).","commonSituations":"Prometheus down or restarting, wrong address/port in the store or query configuration, query_range hitting the max samples/timeout limit and returning 422/503, DNS failures, or mTLS/network policy blocking the call.","solutions":["Check the wrapped inner error: if it's a status code, curl the same URL to see the upstream JSON error (e.g. 'query timeout, execution timeout' with 503) and tune --query.timeout / narrow the range or step.","Verify the endpoint address is reachable from this process (DNS, port, firewall, TLS certificates).","Retry with backoff for transient 5xx/unavailable responses; the client supports retries via TLSConfig / retry options where configured.","Reduce query cost (smaller range, larger step, more selective matchers) if the failure is a resource/size limit."],"exampleFix":"// before\nmatrix, _, _, err := client.QueryRange(ctx, base, \"up\", start, end, 5, opts) // end-start = 90 days, step 5s\n// after\nmatrix, _, _, err := client.QueryRange(ctx, base, \"up\", start, end, 60, opts) // larger step, narrower range\nif err != nil {\n    if strings.Contains(err.Error(), \"503\") { /* backoff and retry */ }\n}","handlingStrategy":"retry","validationCode":"// Reachability pre-check before issuing a range query\nconn, err := net.DialTimeout(\"tcp\", host+\":9090\", 2*time.Second)\nif err != nil {\n    return fmt.Errorf(\"prometheus endpoint unreachable: %w\", err)\n}\nconn.Close()","typeGuard":"func isHTTPFailure(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"read query range response\")\n}","tryCatchPattern":"var matrix model.Matrix\nbackoff := time.Second\nfor i := 0; i < 3; i++ {\n    m, _, _, err := client.QueryRange(ctx, base, q, st, en, step, opts)\n    if err == nil { matrix = m; break }\n    if !isHTTPFailure(err) || !strings.Contains(err.Error(), \"50\") { return err }\n    time.Sleep(backoff); backoff *= 2\n}","preventionTips":["Monitor endpoint health with a lightweight /-/healthy probe before queries","Size range/step within --query.max-samples and timeout limits","Enable client-side retries with backoff for transient 5xx","Verify DNS, firewall, and TLS config when deploying to new environments"],"tags":["network","http","prometheus","timeout"],"backgroundTag":"http-request-failed","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"}