{"record":{"id":"e0b721d0684784a2","repo":"risingwavelabs/risingwave","slug":"sending-stream-load-request-failed","errorCode":null,"errorMessage":"sending stream load request failed","messagePattern":"sending stream load request failed","errorType":"exception","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/doris_starrocks_connector.rs","lineNumber":421,"sourceCode":"/// Please note, the FE address that user specified might be a FE follower not the leader, in this case,\n/// the follower FE will redirect request to leader FE and then to BE.\nasync fn send_stream_load_request(\n    client: Client,\n    mut request: Request,\n    fe_host: &str,\n) -> Result<StreamLoadResponse> {\n    // possible redirection paths:\n    // RW <-> follower FE -> leader FE -> BE\n    // RW <-> leader FE -> BE\n    // RW <-> leader FE\n    for _ in 0..2 {\n        let original_http_port = request.url().port();\n        let mut request_for_redirection = request\n            .try_clone()\n            .ok_or_else(|| SinkError::DorisStarrocksConnect(anyhow!(\"Can't clone request\")))?;\n        let resp = client.execute(request).await.map_err(|err| {\n            SinkError::DorisStarrocksConnect(\n                anyhow!(err).context(\"sending stream load request failed\"),\n            )\n        })?;\n        let be_url = try_get_be_url(&resp, fe_host)?;\n        match be_url {\n            Some(be_url) => {\n                // we used an unconventional method to detect if we are currently redirecting to FE leader, i.e.,\n                // by comparing the port of the redirected url with that of the original request, if they are same, we consider\n                // this is a FE address. Because in practice, no one would deploy their `StarRocks` cluster with the same\n                // http port for both FE and BE. However, this is a potentially problematic assumption,\n                // we may investigate a better way to do this. For example, we could use the `show backends` command to check\n                // if the host of the redirected url is in the list. However, `show backends` requires\n                // the system-level privilege, which could break the backward compatibility.\n                let redirected_port = be_url.port();\n                *request_for_redirection.url_mut() = be_url;\n                if redirected_port == original_http_port {\n                    // redirected to FE, continue another round.\n                    request = request_for_redirection;\n                } else {","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/doris_starrocks_connector.rs#L403-L439","documentation":"This error wraps a reqwest client failure while executing the Doris/StarRocks stream load HTTP request inside send_stream_load_request. It fires when the HTTP request itself could not be completed at the transport level (connection failed, DNS resolution failed, timeout, TLS error), before any HTTP response is available. The original reqwest error is preserved as the anyhow context.","triggerScenarios":"client.execute(request) returns Err in send_stream_load_request — e.g. the FE/BE host is unreachable, DNS fails, the connection is refused or reset, TLS handshake fails, or the per-request timeout (stream_load_http_timeout for non-load requests, tokio::timeout for load requests) elapses.","commonSituations":"Wrong FE host/port in the sink connector URL (e.g. using the MySQL query port 9030 instead of the FE HTTP port 8030); FE/BE nodes down or restarting; network/firewall blocking the HTTP port between RisingWave and the cluster; k8s service DNS misconfiguration; long stream loads exceeding stream_load_http_timeout_ms.","solutions":["Verify the connector URL uses the FE HTTP port (typically 8030 for Doris/StarRocks), not the MySQL port 9030 or BE port","Check network reachability from the RisingWave node: curl -v http://<fe_host>:<http_port>/api/transaction/begin","Confirm FE and BE processes are running (show frontends / show backends via MySQL client) and not restarting under load","Increase stream_load_http_timeout_ms if errors are timeouts on large loads","Inspect the wrapped reqwest error message (source of the anyhow chain) to distinguish connect-refused vs DNS vs timeout and fix accordingly"],"exampleFix":"// before\nurl = 'http://fe-host:9030'  // MySQL port, no HTTP service\n// after\nurl = 'http://fe-host:8030'  // FE http_port","handlingStrategy":"retry","validationCode":"let url: reqwest::Url = endpoint.parse()?;\nassert!(matches!(url.scheme(), \"http\" | \"https\"), \"endpoint must be http(s)\");\nassert!(url.host_str().is_some(), \"endpoint must contain a host\");\nassert_ne!(url.port_or_known_default(), Some(9030), \"9030 is the MySQL port; use the FE http_port (e.g. 8030)\");\n// then: before creating the sink, probe once:\n// reqwest::get(format!(\"{}api/health\", endpoint_trimmed)).await?;","typeGuard":"fn is_reachable_transport_error(err: &SinkError) -> bool {\n    let msg = err.to_string();\n    msg.contains(\"sending stream load request failed\")\n}","tryCatchPattern":"match sender.send().await {\n    Ok(bytes) => { /* parse stream load response */ }\n    Err(e) if e.to_string().contains(\"sending stream load request failed\") => {\n        // inspect reqwest source: connect vs timeout vs dns; retry with backoff after verifying FE/BE health\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always use the FE http_port (8030/8333), never the MySQL port 9030, in the connector URL","Monitor FE/BE process health and leader election before/at sink startup","Set stream_load_http_timeout_ms generously for large batch loads","Run connectivity checks (curl to the FE HTTP endpoint) from the RisingWave host as part of deployment validation"],"tags":["network","http","doris","starrocks","sink"],"backgroundTag":"network-request-failed","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"}