risingwavelabs/risingwave · error · SinkError
Can't get doris BE url in header
Error message
Can't get doris BE url in header
What it means
Doris stream load uses a two-step redirect: the FE answers 307 TEMPORARY_REDIRECT with the BE URL in the `location` header. If a 307 arrives without that header, or the header value is not valid UTF-8, try_get_be_url raises this error because the actual BE endpoint cannot be determined.
Source
Thrown at src/connector/src/sink/doris_starrocks_connector.rs:192
pub fn build(self) -> HashMap<String, String> {
self.header
}
}
/// Try getting BE url from a redirected response, returning `Ok(None)` indicates this request does
/// not redirect.
///
/// The reason we handle the redirection manually is that if we let `reqwest` handle the redirection
/// automatically, it will remove sensitive headers (such as Authorization) during the redirection,
/// and there's no way to prevent this behavior.
fn try_get_be_url(resp: &Response, fe_host: &str) -> Result<Option<Url>> {
match resp.status() {
StatusCode::TEMPORARY_REDIRECT => {
let be_url = resp
.headers()
.get("location")
.ok_or_else(|| {
SinkError::DorisStarrocksConnect(anyhow!("Can't get doris BE url in header",))
})?
.to_str()
.context("Can't get doris BE url in header")
.map_err(SinkError::DorisStarrocksConnect)?
.to_owned();
let mut parsed_be_url = Url::parse(&be_url)
.map_err(|err| SinkError::DorisStarrocksConnect(anyhow!(err)))?;
if fe_host != LOCALHOST && fe_host != LOCALHOST_IP {
let be_host = parsed_be_url.host_str().ok_or_else(|| {
SinkError::DorisStarrocksConnect(anyhow!("Can't get be host from url"))
})?;
if be_host == LOCALHOST || be_host == LOCALHOST_IP {
// if be host is 127.0.0.1, we may can't connect to it directly,
// so replace it with fe host
parsed_be_urlView on GitHub (pinned to 6469eb736d)
Solutions
- Check any proxy/LB between RisingWave and Doris FE preserves the Location header on 307 responses.
- Verify the Doris FE is healthy and reachable directly (bypass proxies).
- Inspect the raw response headers with curl -v against the stream-load endpoint.
- Upgrade Doris if the FE is known to emit broken redirects.
Defensive patterns
Strategy: try-catch
Try / catch
match send_stream_load_request(&mut req).await {
Err(SinkError::DorisStarrocksConnect(e)) if e.to_string().contains("Can't get doris BE url in header") => {
eprintln!("FE sent 307 without a usable Location header; check proxies");
}
other => other?,
} Prevention
- Ensure proxies/LBs preserve the Location header on 307 responses.
- Point the sink directly at the Doris FE when possible.
- Test with `curl -v -X PUT` against the stream-load endpoint to inspect redirects.
When it happens
Trigger: Receiving HTTP 307 from the Doris FE with no `location` header, or a non-ASCII/non-UTF-8 location value, during send_stream_load_request or connector build.
Common situations: Misconfigured proxy/load balancer stripping the Location header; malformed FE redirect responses; non-ASCII hostnames in the cluster.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Can't find data
- Insert error: {:?}, error url: {:?}
- Can't get be host from url
- Can't get doris BE url
- redirection occur more than twice when sending stream load r
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/c9b03e038461f7d8.
Report an issue: GitHub.