thanos-io/thanos · error
unable to create request
Error message
unable to create request
What it means
After building the URL (base + /api/v1/read), startPromRemoteRead creates the POST http.Request via http.NewRequest. If the URL is invalid or malformed, the wrapped error "unable to create request" is returned. This almost always means the store's configured base address is not a valid absolute HTTP URL.
Solutions
- Fix the store's base address to be a full absolute URL including scheme (http://host:9090)
- Validate the address at store-creation time with url.Parse before issuing queries
- Check config files/env vars feeding the address for empty or malformed values
- Verify path joining does not produce an invalid URL when the base path is unusual
Example fix
// before address: "prometheus:9090" // after address: "http://prometheus:9090"
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(addr)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("invalid store address %q: need absolute URL with scheme", addr)
} Try / catch
resp, err := store.Series(ctx, req)
if err != nil && strings.Contains(err.Error(), "unable to create request") {
// address malformed: fix --store-address / config and re-create the store
} Prevention
- Always include the scheme (http:// or https://) in store addresses
- Validate addresses at startup, not on first query
- Escape/trim whitespace from templated or env-provided addresses
When it happens
Trigger: Constructing a PrometheusStore with --store-address / base URL that is empty, missing scheme (e.g. "prometheus:9090" instead of "http://prometheus:9090"), or contains characters http.NewRequest rejects (spaces, control chars).
Common situations: Typo in store address flag; missing http:// scheme prefix in static config or file_sd targets; environment interpolation producing an empty address; invalid characters from templated addresses.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- is 'web.enable-admin-api' flag enabled? got non-200…
- creating request to downstream URL
- failed to create matchers cache
- failed to validate prometheus flags
- failed to get prometheus version
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/85fea78978a07d5f.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/store/prometheus.go:472
return chks, nil
}
func (p *PrometheusStore) startPromRemoteRead(ctx context.Context, q *prompb.Query) (presp *http.Response, err error) {
reqb, err := proto.Marshal(&prompb.ReadRequest{
Queries: []*prompb.Query{q},
AcceptedResponseTypes: p.remoteReadAcceptableResponses,
})
if err != nil {
return nil, errors.Wrap(err, "marshal read request")
}
u := *p.base
u.Path = path.Join(u.Path, "api/v1/read")
preq, err := http.NewRequest("POST", u.String(), bytes.NewReader(snappy.Encode(nil, reqb)))
if err != nil {
return nil, errors.Wrap(err, "unable to create request")
}
preq.Header.Add("Content-Encoding", "snappy")
preq.Header.Set("Content-Type", "application/x-stream-protobuf")
preq.Header.Set("X-Prometheus-Remote-Read-Version", "0.1.0")
preq.Header.Set("User-Agent", clientconfig.ThanosUserAgent)
presp, err = p.client.Do(preq.WithContext(ctx))
if err != nil {
return nil, errors.Wrap(err, "send request")
}
if presp.StatusCode/100 != 2 {
// Best effort read.
b, err := io.ReadAll(presp.Body)
if err != nil {
level.Error(p.logger).Log("msg", "failed to read response from non 2XX remote read request", "err", err)
}
_ = presp.Body.Close()
return nil, errors.Errorf("request failed with code %s; msg %s", presp.Status, string(b))View on GitHub (pinned to 35b8b99117)