{"record":{"id":"d42244fd42d4e9ee","repo":"jaegertracing/jaeger","slug":"failed-to-build-transport-pool-w","errorCode":null,"errorMessage":"failed to build transport pool: %w","messagePattern":"failed to build transport pool: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/elasticsearch/esclient/transport.go","lineNumber":94,"sourceCode":"\ttransportOpts := []elastictransport.Option{\n\t\telastictransport.WithURLs(urls...),\n\t\telastictransport.WithTransport(base),\n\t\telastictransport.WithDisableRetry(),\n\t}\n\tif opts.compressRequestBody {\n\t\t// Defaults to gzip.DefaultCompression, matching the level the olivere\n\t\t// client used before it was retired. The pool gzips the body and sets\n\t\t// Content-Encoding before handing the request to base, so the auth stack\n\t\t// below (notably the SigV4 signer) signs the compressed payload that\n\t\t// actually goes on the wire.\n\t\ttransportOpts = append(transportOpts, elastictransport.WithCompression())\n\t}\n\tif opts.logLevel != \"\" && opts.logger != nil {\n\t\ttransportOpts = append(transportOpts, elastictransport.WithLogger(newZapLogger(opts.logLevel, opts.logger)))\n\t}\n\tpool, err := newPool(transportOpts...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to build transport pool: %w\", err)\n\t}\n\trc := &rawClient{pool: pool, base: base}\n\tif opts.discoverNodes {\n\t\t// Node discovery (sniffing): query one seed node once at startup and add\n\t\t// the cluster's other nodes to the pool. This is a one-shot call — no\n\t\t// background goroutine is scheduled (that would require a discovery\n\t\t// interval), so close() still has nothing to stop. Left off by default\n\t\t// because a cluster that publishes addresses the client cannot reach (a\n\t\t// common AWS/proxy setup) would break the pool. DiscoverNodesContext\n\t\t// tolerates a nil ctx (it falls back to context.Background()).\n\t\tif err := pool.DiscoverNodesContext(ctx); err != nil {\n\t\t\t// The discovery request opened a connection through base; release it,\n\t\t\t// since we are abandoning this client instead of returning it for the\n\t\t\t// caller to Close.\n\t\t\trc.close()\n\t\t\treturn nil, fmt.Errorf(\"failed to discover Elasticsearch nodes (sniffing): %w\", err)\n\t\t}\n\t}","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/storage/elasticsearch/esclient/transport.go#L76-L112","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Inspect the wrapped inner error (%w) to see the pool's actual failure reason and fix the underlying cause.","Verify all servers entries are absolute http(s) URLs with scheme and host (see the URL validation that runs just before pool construction).","Reduce option complexity: retry is disabled by design, so check compression and logger options for bad values (e.g. invalid log level).","If it persists with valid config, check the elastic-transport-go library version for known construction bugs."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"for _, s := range cfg.Servers {\n\tu, err := url.Parse(s)\n\tif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n\t\treturn fmt.Errorf(\"pre-validate server %q failed\", s)\n\t}\n}","typeGuard":null,"tryCatchPattern":"rc, err := esclient.NewClient(...)\nif err != nil {\n\tvar poolErr *fmt.wrapError // inspect unwrapped chain for the pool's root cause\n\troot := err\n\tfor errors.Unwrap(root) != nil { root = errors.Unwrap(root) }\n\treturn fmt.Errorf(\"elasticsearch client init failed: %w (root: %v)\", err, root)\n}","preventionTips":["Pre-validate all server URLs and option values before constructing the client.","Keep the elastic-transport-go dependency current to avoid fixed construction bugs.","Log the full error chain (errors.Unwrap loop) so the pool's root cause is visible in startup logs.","Fail fast at config load time rather than at client construction to isolate config vs library issues."],"tags":["elasticsearch","transport","initialization"],"backgroundTag":"transport-pool-init-failed","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}