cocoindex-io/cocoindex · error · DorisStreamLoadError

Invalid response: {text[:200]}

Error message

Invalid response: {text[:200]}

What it means

After a stream load, the connector expects the FE/BE response body to be JSON (per Doris stream load protocol). If the body is not parseable JSON, the connector cannot determine load status and raises DorisStreamLoadError with status 'ParseError', including the first 200 chars of the body.

Source

Thrown at python/cocoindex/connectors/doris/_target.py:649

                status_code, _, text = await _send(rewritten)
        else:
            async with session.put(
                url, data=data, headers=headers, timeout=load_timeout
            ) as response:
                status_code = response.status
                text = await response.text()

        if status_code in (401, 403):
            raise DorisAuthError(
                f"Authentication failed: HTTP {status_code}",
                host=config.fe_host,
                port=config.fe_http_port,
            )

        try:
            result: dict[str, Any] = json.loads(text)
        except json.JSONDecodeError:
            raise DorisStreamLoadError(
                f"Invalid response: {text[:200]}", status="ParseError"
            )

        load_status = result.get("Status", "Unknown")
        if load_status not in ("Success", "Publish Timeout"):
            raise DorisStreamLoadError(
                result.get("Message", "Unknown error"),
                status=load_status,
                error_url=result.get("ErrorURL"),
                loaded_rows=result.get("NumberLoadedRows", 0),
                filtered_rows=result.get("NumberFilteredRows", 0),
            )
        return result

    retry_config = RetryConfig(
        max_retries=config.max_retries,
        base_delay=config.retry_base_delay,
        max_delay=config.retry_max_delay,

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Confirm fe_http_port is the FE HTTP port (default 8030), not the MySQL port (9030)
  2. Check whether a proxy/load balancer sits in front of Doris and bypass it or fix its error responses
  3. Inspect the returned body (shown in the error) to identify the responder and fix routing/auth

Example fix

// before
DorisConfig(fe_host="fe", fe_http_port=9030)  # mysql port
// after
DorisConfig(fe_host="fe", fe_http_port=8030)  # http port
Defensive patterns

Strategy: try-catch

Validate before calling

# verify FE HTTP port reachable and returns JSON
import urllib.request
r = urllib.request.urlopen(f"http://{host}:{port}")
assert r.headers.get("Content-Type", "").startswith("text/json") or True

Try / catch

try:
    await target.sync()
except DorisStreamLoadError as e:
    if e.status == "ParseError":
        logger.error("Non-JSON stream load response: %s", e)

Prevention

When it happens

Trigger: The stream load HTTP response returns HTML (proxy error page, auth login page), plain text, or a redirect body instead of the expected JSON report; typically due to wrong port, redirect handling, or an intermediary proxy.

Common situations: Pointing fe_http_port at the MySQL query port (9030) instead of the HTTP port (8030); a reverse proxy returning HTML error pages; gzip/compressed responses not decompressed.

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 cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/523dafe71b385ca1. Report an issue: GitHub.