risingwavelabs/risingwave · error · SinkError
Can't get fe host from url
Error message
Can't get fe host from url
What it means
InserterInnerBuilder::new parses the FE URL provided in the sink options and extracts its host with host_str(). If the URL parses but contains no host (e.g. a scheme-less or path-only string), this error is raised because all stream-load requests are built from the FE host.
Source
Thrown at src/connector/src/sink/doris_starrocks_connector.rs:248
url: String,
header: HashMap<String, String>,
#[expect(dead_code)]
sender: Option<Sender>,
fe_host: String,
stream_load_http_timeout: Duration,
}
impl InserterInnerBuilder {
pub fn new(
url: String,
db: String,
table: String,
header: HashMap<String, String>,
stream_load_http_timeout_ms: u64,
) -> Result<Self> {
let fe_host = Url::parse(&url)
.map_err(|err| SinkError::DorisStarrocksConnect(anyhow!(err)))?
.host_str()
.ok_or_else(|| SinkError::DorisStarrocksConnect(anyhow!("Can't get fe host from url")))?
.to_owned();
let url = format!("{}/api/{}/{}/_stream_load", url, db, table);
let stream_load_http_timeout = Duration::from_millis(stream_load_http_timeout_ms);
Ok(Self {
url,
sender: None,
header,
fe_host,
stream_load_http_timeout,
})
}
fn build_request(&self, uri: String) -> Result<RequestBuilder> {
let client = Client::builder()
.pool_idle_timeout(POOL_IDLE_TIMEOUT)
.redirect(redirect::Policy::none()) // we handle redirect by ourselves
.build()View on GitHub (pinned to 6469eb736d)
Solutions
- Set the `url` option to a full URL with scheme and host, e.g. `http://fe-host:8030`.
- Verify no empty/placeholder values in the WITH clause (unresolved template variables).
- Wrap IPv6 literals in brackets: `http://[::1]:8030`.
- Test the URL with a quick curl to the FE port before creating the sink.
Example fix
// before
WITH ('connector'='doris', 'url'='fe-host:8030', ...)
// after
WITH ('connector'='doris', 'url'='http://fe-host:8030', ...) Defensive patterns
Strategy: validation
Validate before calling
fn validate_fe_url(u: &str) -> Result<(), String> {
match url::Url::parse(u) {
Ok(p) if p.host_str().is_some() => Ok(()),
_ => Err(format!("doris `url` must include scheme and host, got: {u}")),
}
} Type guard
fn fe_host(u: &str) -> Option<&str> {
url::Url::parse(u).ok().and_then(|p| p.host_str())
} Try / catch
match build_inserter(url, db, table, header, timeout).await {
Err(SinkError::DorisStarrocksConnect(e)) if e.to_string().contains("Can't get fe host from url") => {
eprintln!("fix the doris `url` option: {e}");
}
other => other?,
} Prevention
- Always use full URLs like http://fe-host:8030 in the `url` option.
- Check for unfilled config templates or empty environment substitutions.
- Bracket IPv6 literals in the URL.
When it happens
Trigger: Configuring the Doris sink `url` option as something Url::parse accepts but that has no host component, such as 'http:///api' or a relative path, during sink build.
Common situations: Typos dropping the hostname; forgetting the scheme so the URL parser treats text differently; templated config values left unfilled; IPv6 hosts without brackets.
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.
Related errors
- `{}` must be {}, or {}
- Primary key not defined for upsert doris sink (please define
- Can't get be host from url
- path should start with 's3://','s3a://'(s3) ,gs://(gcs) or f
- If you want to use upsert, please set the keysType of doris
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/3b26a921fd10e390.
Report an issue: GitHub.