{"record":{"id":"3b26a921fd10e390","repo":"risingwavelabs/risingwave","slug":"can-t-get-fe-host-from-url","errorCode":null,"errorMessage":"Can't get fe host from url","messagePattern":"Can't get fe host from url","errorType":"exception","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/doris_starrocks_connector.rs","lineNumber":248,"sourceCode":"    url: String,\n    header: HashMap<String, String>,\n    #[expect(dead_code)]\n    sender: Option<Sender>,\n    fe_host: String,\n    stream_load_http_timeout: Duration,\n}\nimpl InserterInnerBuilder {\n    pub fn new(\n        url: String,\n        db: String,\n        table: String,\n        header: HashMap<String, String>,\n        stream_load_http_timeout_ms: u64,\n    ) -> Result<Self> {\n        let fe_host = Url::parse(&url)\n            .map_err(|err| SinkError::DorisStarrocksConnect(anyhow!(err)))?\n            .host_str()\n            .ok_or_else(|| SinkError::DorisStarrocksConnect(anyhow!(\"Can't get fe host from url\")))?\n            .to_owned();\n        let url = format!(\"{}/api/{}/{}/_stream_load\", url, db, table);\n        let stream_load_http_timeout = Duration::from_millis(stream_load_http_timeout_ms);\n\n        Ok(Self {\n            url,\n            sender: None,\n            header,\n            fe_host,\n            stream_load_http_timeout,\n        })\n    }\n\n    fn build_request(&self, uri: String) -> Result<RequestBuilder> {\n        let client = Client::builder()\n            .pool_idle_timeout(POOL_IDLE_TIMEOUT)\n            .redirect(redirect::Policy::none()) // we handle redirect by ourselves\n            .build()","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/doris_starrocks_connector.rs#L230-L266","documentation":"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.","triggerScenarios":"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.","commonSituations":"Typos dropping the hostname; forgetting the scheme so the URL parser treats text differently; templated config values left unfilled; IPv6 hosts without brackets.","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."],"exampleFix":"// before\nWITH ('connector'='doris', 'url'='fe-host:8030', ...)\n// after\nWITH ('connector'='doris', 'url'='http://fe-host:8030', ...)","handlingStrategy":"validation","validationCode":"fn validate_fe_url(u: &str) -> Result<(), String> {\n    match url::Url::parse(u) {\n        Ok(p) if p.host_str().is_some() => Ok(()),\n        _ => Err(format!(\"doris `url` must include scheme and host, got: {u}\")),\n    }\n}","typeGuard":"fn fe_host(u: &str) -> Option<&str> {\n    url::Url::parse(u).ok().and_then(|p| p.host_str())\n}","tryCatchPattern":"match build_inserter(url, db, table, header, timeout).await {\n    Err(SinkError::DorisStarrocksConnect(e)) if e.to_string().contains(\"Can't get fe host from url\") => {\n        eprintln!(\"fix the doris `url` option: {e}\");\n    }\n    other => other?,\n}","preventionTips":["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."],"tags":["rust","sink","doris","url","config"],"backgroundTag":"invalid-url-format","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}