risingwavelabs/risingwave · error · SinkError

transport build error

Error message

transport build error: {e}

What it means

After parsing the URL, build_client assembles the elasticsearch/opensearch crate TransportBuilder and builds a Transport; any error from TransportBuilder::build() (e.g. bad proxy configuration, TLS setup failure, empty connection pool) is wrapped with this message.

Solutions

  1. Read the wrapped underlying error from the message to identify which transport parameter failed.
  2. Recheck url correctness and scheme (http vs https) — a wrong scheme can break TLS transport setup.
  3. Remove/correct proxy settings (e.g. conflicting HTTP_PROXY env vars) if a proxy is involved.
  4. Verify the cluster is reachable with curl from the RisingWave node and that the crate version supports the cluster's API/TLS version.

Example fix

// before
'url' = 'https://localhost:9200'  // https on a plain-http node
// after
'url' = 'http://localhost:9200'
Defensive patterns

Strategy: try-catch

Validate before calling

curl -sk 'https://es.example.com:9243' -u elastic:secret   # confirm reachability, scheme and TLS before building the sink

Try / catch

match err { SinkError::ElasticSearchOpenSearch(e) if e.to_string().contains("transport build error") => inspect_source_and_fix_transport_config(), _ => return Err(err) }

Prevention

When it happens

Trigger: new() -> build_client() -> transport_builder.build() returns Err. Commonly misconfigured proxy settings (transport builder proxy), invalid TLS configuration, or an underlying transport construction failure after URL parsing succeeded.

Common situations: HTTPS endpoint with unparseable certificate setup; proxy env/config incompatibilities; issues constructing the single-node connection pool; version drift between the elasticsearch/opensearch crate and the cluster.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/5ac1107351dc044e. Report an issue: GitHub.

Appendix: source

Thrown at src/connector/src/sink/elasticsearch_opensearch/elasticsearch_opensearch_config.rs:220

            Ok(())
        };
        let url =
            Url::parse(&self.url).map_err(|e| SinkError::ElasticSearchOpenSearch(anyhow!(e)))?;
        if connector.eq(ES_SINK) {
            let mut transport_builder = elasticsearch::http::transport::TransportBuilder::new(
                elasticsearch::http::transport::SingleNodeConnectionPool::new(url),
            );
            if let Some(username) = &self.username
                && let Some(password) = &self.password
            {
                transport_builder = transport_builder.auth(
                    elasticsearch::auth::Credentials::Basic(username.clone(), password.clone()),
                );
            }
            check_username_password()?;
            let transport = transport_builder
                .build()
                .map_err(|e| SinkError::ElasticSearchOpenSearch(anyhow!(e)))?;
            let client = elasticsearch::Elasticsearch::new(transport);
            Ok(ElasticSearchOpenSearchClient::ElasticSearch(client))
        } else if connector.eq(OPENSEARCH_SINK) {
            let mut transport_builder = opensearch::http::transport::TransportBuilder::new(
                opensearch::http::transport::SingleNodeConnectionPool::new(url),
            );
            if let Some(username) = &self.username
                && let Some(password) = &self.password
            {
                transport_builder = transport_builder.auth(opensearch::auth::Credentials::Basic(
                    username.clone(),
                    password.clone(),
                ));
            }
            check_username_password()?;
            let transport = transport_builder
                .build()
                .map_err(|e| SinkError::ElasticSearchOpenSearch(anyhow!(e)))?;

View on GitHub (pinned to 6469eb736d)