risingwavelabs/risingwave · error · SinkError

failed to parse response body

Error message

failed to parse response body

What it means

After the streamed PUT to the Doris/StarRocks BE finishes with a non-200 status, RisingWave tries to convert the raw response bytes into a UTF-8 String to include in the error message. If the body is not valid UTF-8, `String::from_utf8` fails and this error is thrown (wrapping the original non-OK status handling). It is a secondary error masking the real HTTP failure.

Source

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

        let handle: JoinHandle<Result<Vec<u8>>> = tokio::spawn(async move {
            let response = builder
                .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>;

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Check the status code in the full error chain — the root cause is the non-OK HTTP response, not the encoding
  2. curl the same stream-load endpoint to see the real response/status
  3. Fix the underlying connectivity/config issue (auth, URL, TLS) that caused the non-200 response
  4. If a proxy is in the path, bypass it or configure it to return plain-text errors

Example fix

null
Defensive patterns

Strategy: try-catch

Try / catch

match res {
    Err(e) if e.to_string().contains("failed to parse response body") => {
        // inspect the chained context: the real cause is the non-OK HTTP status;
        // log status/body bytes and check for proxy interference
    }
    r => r?,
}

Prevention

When it happens

Trigger: `build()` spawns the stream-load request; the BE returns a non-200 status (e.g. 307, 404, 500) and the response body contains non-UTF-8 bytes (compressed body, binary error page, or HTML with invalid encoding).

Common situations: Proxy/gateway returning gzipped or binary error pages; BE returning a redirect body with unusual encoding; misconfigured TLS or wrong scheme producing garbage responses.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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