risingwavelabs/risingwave · error · SinkError
Url::parse error: {e}
Error message
Url::parse error: {e} What it means
build_client parses the configured `url` with the `url` crate before constructing the transport; a parse failure (missing scheme, invalid characters, empty string) is surfaced as SinkError::ElasticSearchOpenSearch with this message.
Source
Thrown at src/connector/src/sink/elasticsearch_opensearch/elasticsearch_opensearch_config.rs:205
Ok(config)
}
pub fn build_client(&self, connector: &str) -> Result<ElasticSearchOpenSearchClient> {
let check_username_password = || -> Result<()> {
if self.username.is_some() && self.password.is_none() {
return Err(SinkError::Config(anyhow!(
"please set the password when the username is set."
)));
}
if self.username.is_none() && self.password.is_some() {
return Err(SinkError::Config(anyhow!(
"please set the username when the password is set."
)));
}
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) {View on GitHub (pinned to 6469eb736d)
Solutions
- Set `url` to a well-formed absolute URL like `http://localhost:9200` or `https://es.example.com:9243`.
- Strip whitespace/quotes and drop any path suffixes like `/_bulk` — only the base URL is needed.
- Check the full wrapped Url::parse error in the message for the exact character problem.
Example fix
// before 'url' = 'localhost:9200' // after 'url' = 'http://localhost:9200'
Defensive patterns
Strategy: validation
Validate before calling
-- sanity check the URL before creating the sink
SELECT 'http://localhost:9200' = 'http://localhost:9200';
-- or in shell:
-- python3 -c "from urllib.parse import urlparse; u=urlparse('http://localhost:9200'); assert u.scheme in ('http','https') and u.netloc" Try / catch
match err { SinkError::ElasticSearchOpenSearch(e) if e.to_string().contains("Url::parse error") => fix_url_scheme_and_recreate(), _ => return Err(err) } Prevention
- Always include the scheme: http:// or https://.
- Use only the base URL — no /_bulk path, no spaces or quotes.
- Test the URL with `curl <url>` from the RisingWave host first.
When it happens
Trigger: The `url` option in the sink/connection config is malformed: missing http(s):// scheme, contains spaces or illegal characters, or is empty when the config is built.
Common situations: Forgetting the `http://`/`https://` prefix; trailing slashes with query fragments; hostnames with underscores; URL copied with surrounding quotes/spaces.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid field: {}, allowed fields: {:?}
- please set the password when the username is set.
- please set the username when the password is set.
- Cannot find {}
- HTTP sink requires url option when schema has exactly 1 colu
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/8c6f41d03e94e770.
Report an issue: GitHub.