{"record":{"id":"e7fac1467bd128de","repo":"thanos-io/thanos","slug":"perform-s-request-against-s","errorCode":null,"errorMessage":"perform %s request against %s","messagePattern":"perform (.+?) request against (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/promclient/promclient.go","lineNumber":135,"sourceCode":"\n\treq, err := http.NewRequest(method, u.String(), b)\n\tif err != nil {\n\t\treturn nil, 0, errors.Wrapf(err, \"create %s request\", method)\n\t}\n\tif headers != nil {\n\t\treq.Header = headers\n\t}\n\n\tif c.userAgent != \"\" {\n\t\treq.Header.Set(\"User-Agent\", c.userAgent)\n\t}\n\tif method == http.MethodPost {\n\t\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\t}\n\n\tresp, err := c.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, 0, errors.Wrapf(err, \"perform %s request against %s\", method, u.String())\n\t}\n\tdefer runutil.ExhaustCloseWithErrCapture(&err, resp.Body, \"%s: close body\", req.URL.String())\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, resp.StatusCode, errors.Wrap(err, \"read body\")\n\t}\n\tif resp.StatusCode/100 != 2 {\n\t\treturn nil, resp.StatusCode, errors.Errorf(\"expected 2xx response, got %d. Body: %v\", resp.StatusCode, string(body))\n\t}\n\treturn body, resp.StatusCode, nil\n}\n\n// IsWALDirAccessible returns no error if WAL dir can be found. This helps to tell\n// if we have access to Prometheus TSDB directory.\nfunc IsWALDirAccessible(dir string) error {\n\tconst errMsg = \"WAL dir is not accessible. Is this dir a TSDB directory? If yes it is shared with TSDB?\"\n","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/promclient/promclient.go#L117-L153","documentation":"req2xx failed to execute the HTTP request against the Prometheus API: c.Do(req) returned a transport-level error. The message includes the method and target URL. This happens before any response status is available — DNS failure, connection refused, TLS error, or context cancellation.","triggerScenarios":"Any client call (QueryInstant, QueryRange, ExternalLabels, BuildVersion, etc.) where the Prometheus host is unreachable, the port is wrong, TLS fails, or ctx is cancelled mid-request.","commonSituations":"Prometheus down or restarted; sidecar pointed at the wrong address/port; network policy or firewall blocking egress; request context deadline exceeded on slow queries.","solutions":["Check Prometheus is up and listening on the configured URL (curl the URL from the same host)","Inspect the wrapped error: connection refused vs DNS vs timeout indicate different fixes","Increase client timeout / verify ctx cancellation isn't premature","Fix DNS, network policy, or TLS trust configuration as indicated by the cause"],"exampleFix":"// before\nresp, err := client.QueryInstant(ctx, apiCtx, nil)\n// after\nctx, cancel := context.WithTimeout(ctx, 30*time.Second)\ndefer cancel()\nresp, err := client.QueryInstant(ctx, apiCtx, nil)\nif err != nil && status.Code(err) == codes.DeadlineExceeded { /* retry with backoff */ }","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := runutil.Retry(2*time.Second, ctx.Done(), func() error {\n    _, _, err := client.BuildVersion(ctx, promURL)\n    if err != nil && !errors.Is(err, context.Canceled) {\n        return err // transport failure: retry\n    }\n    return nil\n})","preventionTips":["Health-check the Prometheus URL at startup and on a ticker","Set explicit, generous client timeouts","Verify DNS/firewall/egress rules between client and Prometheus","Match scheme and TLS settings to the Prometheus listener"],"tags":["http","network","prometheus"],"backgroundTag":"connection-refused","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"}