BerriAI/litellm · error · RuntimeError

Error receiving chunk from stream: {e}

Error message

Error receiving chunk from stream: {e}

What it means

In the sync chunk-reading loop of BaseModelResponseIterator, a ValueError raised by the underlying response iterator (the provider's HTTP/SSE stream) is re-raised as RuntimeError so it isn't mistaken for a clean stream end. The original error text is preserved after the colon.

Source

Thrown at litellm/llms/base_llm/base_model_iterator.py:142

            return self.chunk_parser(chunk=stripped_json_chunk)
        else:
            return GenericStreamingChunk(
                text="",
                is_finished=False,
                finish_reason="",
                usage=None,
                index=0,
                tool_use=None,
            )

    def __next__(self):
        while True:
            try:
                chunk = self.response_iterator.__next__()
            except StopIteration:
                raise StopIteration
            except ValueError as e:
                raise RuntimeError(f"Error receiving chunk from stream: {e}")

            try:
                str_line = chunk
                if isinstance(chunk, bytes):  # Handle binary data
                    str_line = chunk.decode("utf-8")  # Convert bytes to string
                    index = str_line.find("data:")
                    if index != -1:
                        str_line = str_line[index:]

                # Skip empty lines (common in SSE streams between events).
                # Only apply to str chunks — non-string objects (e.g. Pydantic
                # BaseModel events from the Responses API) must pass through.
                if isinstance(str_line, str) and (not str_line or not str_line.strip()):
                    continue

                # chunk is a str at this point
                return self._handle_string_chunk(str_line=str_line)
            except StopIteration:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Read the original error after 'Error receiving chunk from stream:' to identify the decode/protocol failure
  2. Retry the request — transient stream corruption often resolves; wrap streaming calls in a retry loop
  3. If persistent for one provider, disable streaming for that model (stream=False) to get the full-body error
  4. Upgrade litellm and httpx — byte-decoding edge cases get patched
Defensive patterns

Strategy: retry

Try / catch

try:
    for chunk in litellm.completion(model=m, messages=msgs, stream=True):
        handle(chunk)
except RuntimeError as e:
    if 'Error receiving chunk from stream' in str(e):
        # transient stream corruption: retry once, else degrade to non-streaming
        response = litellm.completion(model=m, messages=msgs, stream=False)
    else:
        raise

Prevention

When it happens

Trigger: The upstream iterator raises ValueError while yielding bytes — e.g. invalid UTF-8 in a chunk being decoded, or an httpx/aiohttp-level protocol error surfacing as ValueError during iteration on a streaming chat completion.

Common situations: A proxy or gateway corrupting SSE bytes; provider sending non-UTF8 payloads mid-stream; reading a stream after the connection was closed and reused; rarely, bugs in provider adapters that raise ValueError in their generators.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/20ab12eda9db452c. Report an issue: GitHub.