{"record":{"id":"ad07c344476bd86a","repo":"risingwavelabs/risingwave","slug":"failed-to-parse-response-body","errorCode":null,"errorMessage":"failed to parse response body","messagePattern":"failed to parse response body","errorType":"exception","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/doris_starrocks_connector.rs","lineNumber":309,"sourceCode":"\n        let handle: JoinHandle<Result<Vec<u8>>> = tokio::spawn(async move {\n            let response = builder\n                .send()\n                .await\n                .map_err(|err| SinkError::DorisStarrocksConnect(anyhow!(err)))?;\n            let status = response.status();\n            let raw = response\n                .bytes()\n                .await\n                .map_err(|err| SinkError::DorisStarrocksConnect(anyhow!(err)))?\n                .into();\n\n            if status == StatusCode::OK {\n                Ok(raw)\n            } else {\n                let response_body = String::from_utf8(raw).map_err(|err| {\n                    SinkError::DorisStarrocksConnect(\n                        anyhow!(err).context(\"failed to parse response body\"),\n                    )\n                })?;\n                Err(SinkError::DorisStarrocksConnect(anyhow!(\n                    \"Failed connection {:?},{:?}\",\n                    status,\n                    response_body\n                )))\n            }\n        });\n        Ok(InserterInner::new(\n            sender,\n            handle,\n            self.stream_load_http_timeout,\n        ))\n    }\n}\n\ntype Sender = UnboundedSender<Bytes>;","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/doris_starrocks_connector.rs#L291-L327","documentation":"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.","triggerScenarios":"`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).","commonSituations":"Proxy/gateway returning gzipped or binary error pages; BE returning a redirect body with unusual encoding; misconfigured TLS or wrong scheme producing garbage responses.","solutions":["Check the status code in the full error chain — the root cause is the non-OK HTTP response, not the encoding","curl the same stream-load endpoint to see the real response/status","Fix the underlying connectivity/config issue (auth, URL, TLS) that caused the non-200 response","If a proxy is in the path, bypass it or configure it to return plain-text errors"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match res {\n    Err(e) if e.to_string().contains(\"failed to parse response body\") => {\n        // inspect the chained context: the real cause is the non-OK HTTP status;\n        // log status/body bytes and check for proxy interference\n    }\n    r => r?,\n}","preventionTips":["Treat this error as a symptom: the underlying stream-load request returned non-200","Remove proxies that return gzip/binary error bodies on the FE/BE path","Check Doris/StarRocks FE/BE logs for the corresponding request"],"tags":["network","sink","doris","encoding","utf-8"],"backgroundTag":"invalid-json-response","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"}