thanos-io/thanos · error

setup downstream roundtripper

Error message

setup downstream roundtripper

What it means

This wraps errors from cortexfrontend.NewDownstreamRoundTripper, which validates the downstream URL and builds the RoundTripper used to forward requests. Failure usually means the --query-frontend.downstream-url is invalid or not an acceptable URL for the transport.

Solutions

  1. Ensure --query-frontend.downstream-url includes a valid scheme, e.g. http://query-frontend:9090.
  2. Check for whitespace, control characters, or typos in the URL flag.
  3. Read the wrapped underlying error for the exact URL parse failure.
  4. Verify the downstream address resolves/reachable once the URL is valid.

Example fix

// before
--query-frontend.downstream-url=query-frontend-query.thanos:9090
// after
--query-frontend.downstream-url=http://query-frontend-query.thanos:9090
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(downstreamURL)
if err != nil || u.Scheme == "" || u.Host == "" {
  return fmt.Errorf("invalid downstream url %q", downstreamURL)
}

Try / catch

rt, err := cortexfrontend.NewDownstreamRoundTripper(url, tripper)
if err != nil {
  return fmt.Errorf("setup downstream roundtripper: %w", err)
}

Prevention

When it happens

Trigger: --query-frontend.downstream-url empty, malformed (no scheme, spaces, control characters), or otherwise rejected when constructing the downstream RoundTripper after a successful tripper transport setup.

Common situations: Misconfigured Kubernetes service DNS name, URL entered with trailing typo, or scheme omitted (e.g. 'query-frontend:9090' instead of 'http://query-frontend:9090').

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/63dabff0c9e9f300. Report an issue: GitHub.

Appendix: source

Thrown at cmd/thanos/query_frontend.go:336

	tripperWare, err := queryfrontend.NewTripperware(cfg.Config, reg, logger)
	if err != nil {
		return errors.Wrap(err, "setup tripperwares")
	}

	// Create a downstream roundtripper.
	downstreamTripperConfContentYaml, err := cfg.DownstreamTripperConfig.CachePathOrContent.Content()
	if err != nil {
		return err
	}
	downstreamTripper, err := parseTransportConfiguration(downstreamTripperConfContentYaml)
	if err != nil {
		return err
	}

	downstreamRT, err := cortexfrontend.NewDownstreamRoundTripper(cfg.DownstreamURL, downstreamTripper)
	if err != nil {
		return errors.Wrap(err, "setup downstream roundtripper")
	}

	// Wrap the downstream RoundTripper into query frontend Tripperware.
	roundTripper := tripperWare(downstreamRT)

	// Create the query frontend transport.
	handler := transport.NewHandler(*cfg.CortexHandlerConfig, roundTripper, logger, nil)
	if cfg.CompressResponses {
		handler = gzhttp.GzipHandler(handler)
	}

	httpProbe := prober.NewHTTP()
	statusProber := prober.Combine(
		httpProbe,
		prober.NewInstrumentation(comp, logger, extprom.WrapRegistererWithPrefix("thanos_", reg)),
	)

	// Configure Request Logging for HTTP calls.

View on GitHub (pinned to 35b8b99117)