jaegertracing/jaeger · error

failed to build transport pool: %w

Error message

failed to build transport pool: %w

What it means

newRawClient constructs the elastic-transport connection pool via elastictransport.NewClient (indirectly, through the newPool var). If the pool cannot be built, the error is wrapped as "failed to build transport pool" and construction of the raw client aborts. This is a constructor-time failure, so the client is unusable before any request is sent.

Source

Thrown at internal/storage/elasticsearch/esclient/transport.go:94

	transportOpts := []elastictransport.Option{
		elastictransport.WithURLs(urls...),
		elastictransport.WithTransport(base),
		elastictransport.WithDisableRetry(),
	}
	if opts.compressRequestBody {
		// Defaults to gzip.DefaultCompression, matching the level the olivere
		// client used before it was retired. The pool gzips the body and sets
		// Content-Encoding before handing the request to base, so the auth stack
		// below (notably the SigV4 signer) signs the compressed payload that
		// actually goes on the wire.
		transportOpts = append(transportOpts, elastictransport.WithCompression())
	}
	if opts.logLevel != "" && opts.logger != nil {
		transportOpts = append(transportOpts, elastictransport.WithLogger(newZapLogger(opts.logLevel, opts.logger)))
	}
	pool, err := newPool(transportOpts...)
	if err != nil {
		return nil, fmt.Errorf("failed to build transport pool: %w", err)
	}
	rc := &rawClient{pool: pool, base: base}
	if opts.discoverNodes {
		// Node discovery (sniffing): query one seed node once at startup and add
		// the cluster's other nodes to the pool. This is a one-shot call — no
		// background goroutine is scheduled (that would require a discovery
		// interval), so close() still has nothing to stop. Left off by default
		// because a cluster that publishes addresses the client cannot reach (a
		// common AWS/proxy setup) would break the pool. DiscoverNodesContext
		// tolerates a nil ctx (it falls back to context.Background()).
		if err := pool.DiscoverNodesContext(ctx); err != nil {
			// The discovery request opened a connection through base; release it,
			// since we are abandoning this client instead of returning it for the
			// caller to Close.
			rc.close()
			return nil, fmt.Errorf("failed to discover Elasticsearch nodes (sniffing): %w", err)
		}
	}

View on GitHub (pinned to 806f444784)

Solutions

  1. Inspect the wrapped inner error (%w) to see the pool's actual failure reason and fix the underlying cause.
  2. Verify all servers entries are absolute http(s) URLs with scheme and host (see the URL validation that runs just before pool construction).
  3. Reduce option complexity: retry is disabled by design, so check compression and logger options for bad values (e.g. invalid log level).
  4. If it persists with valid config, check the elastic-transport-go library version for known construction bugs.
Defensive patterns

Strategy: try-catch

Validate before calling

for _, s := range cfg.Servers {
	u, err := url.Parse(s)
	if err != nil || u.Scheme == "" || u.Host == "" {
		return fmt.Errorf("pre-validate server %q failed", s)
	}
}

Try / catch

rc, err := esclient.NewClient(...)
if err != nil {
	var poolErr *fmt.wrapError // inspect unwrapped chain for the pool's root cause
	root := err
	for errors.Unwrap(root) != nil { root = errors.Unwrap(root) }
	return fmt.Errorf("elasticsearch client init failed: %w (root: %v)", err, root)
}

Prevention

When it happens

Trigger: Calling NewClient/newRawClient where the elastictransport.NewClient call with the configured URLs, base RoundTripper, retry/compression/logger options returns an error (e.g. no valid URLs after option processing).

Common situations: Misconfigured server lists that pass URL parsing but produce an empty/invalid URL set for the pool; defects or unusual option combinations in transport construction; test setups that substitute a failing newPool implementation.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/d42244fd42d4e9ee. Report an issue: GitHub.