thanos-io/thanos · error

failed to create query client

Error message

failed to create query client: %w

What it means

This error is returned when clientconfig.NewClient fails while assembling the query client from the endpoints config and the already-built HTTP client. runRule returns it inside the per-queryCfg loop after the HTTP client was created successfully. It indicates the endpoints/DNS provider combination is invalid rather than an HTTP/TLS problem.

Solutions

  1. Inspect the endpoints section of the failing query config entry; fix URL parsing issues (scheme, host, port).
  2. Check file_sd configs referenced in endpoints exist and are readable.
  3. Validate the whole config with clientconfig.LoadConfigs standalone to get the exact sub-error.
  4. Confirm DNS SRV/MX/etc. sd_configs use resolvable names.

Example fix

// before
endpoints:
  - query-svc  # no scheme
// after
endpoints:
  - http://query-svc:9090
Defensive patterns

Strategy: try-catch

Validate before calling

for _, e := range cfg.Endpoints {
    if _, err := url.Parse(e.URL); err != nil {
        return fmt.Errorf("bad endpoint url %q: %w", e.URL, err)
    }
}

Try / catch

if _, err := clientconfig.NewClient(logger, cfg.HTTPConfig.EndpointsConfig, c, provider.Clone()); err != nil {
    logger.Error("query client build failed", "err", err, "endpoints", cfg.HTTPConfig.EndpointsConfig)
    return err
}

Prevention

When it happens

Trigger: clientconfig.NewClient(logger, cfg.HTTPConfig.EndpointsConfig, c, queryProvider.Clone()) errors for a config entry — usually an endpoints list with invalid URLs or unsupported scheme for the client.

Common situations: Endpoints entry missing scheme or containing an address NewClient cannot parse; mixing static and file_sd endpoint configs incorrectly; empty endpoints list combined with config that NotEmpty() treats as present.

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/cfd56b8cf9b04cb3. Report an issue: GitHub.

Appendix: source

Thrown at cmd/thanos/rule.go:407

		queryClients    []*clientconfig.HTTPClient
		promClients     []*promclient.Client
		grpcEndpointSet *query.EndpointSet
		grpcEndpoints   []string
	)

	queryClientMetrics := extpromhttp.NewClientMetrics(extprom.WrapRegistererWith(prometheus.Labels{"client": "query"}, reg))

	for _, cfg := range queryCfg {
		if cfg.HTTPConfig.NotEmpty() {
			cfg.HTTPConfig.HTTPClientConfig.ClientMetrics = queryClientMetrics
			c, err := clientconfig.NewHTTPClient(cfg.HTTPConfig.HTTPClientConfig, "query")
			if err != nil {
				return fmt.Errorf("failed to create HTTP query client: %w", err)
			}
			c.Transport = tracing.HTTPTripperware(logger, c.Transport)
			queryClient, err := clientconfig.NewClient(logger, cfg.HTTPConfig.EndpointsConfig, c, queryProvider.Clone())
			if err != nil {
				return fmt.Errorf("failed to create query client: %w", err)
			}
			queryClients = append(queryClients, queryClient)
			promClients = append(promClients, promclient.NewClient(queryClient, logger, "thanos-rule"))
			// Discover and resolve query addresses.
			addDiscoveryGroups(g, queryClient, conf.query.dnsSDInterval, logger)
		}

		if cfg.GRPCConfig != nil {
			grpcEndpoints = append(grpcEndpoints, cfg.GRPCConfig.EndpointAddrs...)
		}
	}

	if len(grpcEndpoints) > 0 {
		dialOpts, err := extgrpc.StoreClientGRPCOpts(
			logger,
			reg,
			tracer,
		)

View on GitHub (pinned to 35b8b99117)