risingwavelabs/risingwave · error · SinkError

Failed connection {:?},{:?}

Error message

Failed connection {:?},{:?}

What it means

The BE responded to the stream-load PUT with a status other than 200 OK, so the sink aborts the connection and reports the status plus the decoded response body. This is the primary error for any failed stream-load handshake during `build()`; the body usually contains Doris/StarRocks' own error JSON explaining why the load was rejected.

Source

Thrown at src/connector/src/sink/doris_starrocks_connector.rs:312

                .send()
                .await
                .map_err(|err| SinkError::DorisStarrocksConnect(anyhow!(err)))?;
            let status = response.status();
            let raw = response
                .bytes()
                .await
                .map_err(|err| SinkError::DorisStarrocksConnect(anyhow!(err)))?
                .into();

            if status == StatusCode::OK {
                Ok(raw)
            } else {
                let response_body = String::from_utf8(raw).map_err(|err| {
                    SinkError::DorisStarrocksConnect(
                        anyhow!(err).context("failed to parse response body"),
                    )
                })?;
                Err(SinkError::DorisStarrocksConnect(anyhow!(
                    "Failed connection {:?},{:?}",
                    status,
                    response_body
                )))
            }
        });
        Ok(InserterInner::new(
            sender,
            handle,
            self.stream_load_http_timeout,
        ))
    }
}

type Sender = UnboundedSender<Bytes>;

pub struct InserterInner {
    sender: Option<Sender>,

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Read the response body in the error message — Doris/StarRocks includes a JSON `Status` field with the real reason
  2. Verify credentials and auth headers in the sink `header` config
  3. Confirm the target database/table exists and column names match the sink schema
  4. Check `SHOW BACKENDS;` and BE http_port reachability from RisingWave
  5. Retry if the status is 5xx — BE may have been transiently overloaded
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check table & connectivity before sinking
curl -s -u "$USER:$PASS" -H "label:probe" \
  -H "column_separator:," -T empty.csv \
  http://fe-host:8030/api/db/table/_stream_load | jq -r .Status

Try / catch

match res {
    Err(e) if e.to_string().contains("Failed connection") => {
        // parse status and body from message; retry on 5xx, fix auth/schema on 4xx
    }
    r => r?,
}

Prevention

When it happens

Trigger: `build()`'s spawned request to the BE completes with any non-200 status: 401/407 (auth), 404 (wrong db/table path), 307 loop, 5xx (BE overload/ internal error), or connection closed early.

Common situations: Wrong username/password or missing Basic auth headers; database or table doesn't exist; BE http_port misconfigured; table schema/column mismatch causing load rejection; BE temporarily down.

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


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/80412e92425a20a8. Report an issue: GitHub.