[GH-ISSUE #23920] fix: Stale Content-Encoding header forwarded from upstream APIs causes ZlibError in desktop clients #35636

Closed
opened 2026-04-25 09:48:03 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @pvyswiss on GitHub (Apr 21, 2026).
Original GitHub issue: https://github.com/open-webui/open-webui/issues/23920

Bug Description

Desktop clients (OpenCode Desktop, OnlyOffice plugin) receive Decompression error: ZlibError when streaming SSE from Claude/OpenAI models through Open WebUI's API proxy. The Web UI works fine.

Related to: #23917 (Bug 1)

Root Cause

aiohttp sends Accept-Encoding: gzip to upstream APIs. When the upstream responds with Content-Encoding: gzip, aiohttp auto-decompresses the response body but keeps the stale Content-Encoding: gzip header (see aiohttp#4462).

openai.py forwards all upstream headers verbatim via headers=dict(r.headers) at 4 StreamingResponse locations. The client receives Content-Encoding: gzip header with plain-text body, tries to decompress, and fails.

Fix

Strip encoding headers that become stale after aiohttp auto-decompression:

_STRIP_PROXY_HEADERS = frozenset({'Content-Encoding', 'Content-Length', 'Transfer-Encoding'})

def _clean_proxy_headers(raw_headers) -> dict:
    return {k: v for k, v in raw_headers.items() if k not in _STRIP_PROXY_HEADERS}

Applied at all 4 StreamingResponse locations in openai.py.

Impact

  • Web UI: None (browser path doesn't use the OpenAI proxy for SSE)
  • API clients: All desktop/programmatic clients that honor Content-Encoding are fixed

File

backend/open_webui/routers/openai.py

Reproduction

curl --compressed -sN -H "Authorization: Bearer $KEY" \
  -d '{"model":"claude-model","messages":[{"role":"user","content":"hi"}],"stream":true}' \
  http://localhost:3000/api/chat/completions
# Result: ZlibError or garbled output
Originally created by @pvyswiss on GitHub (Apr 21, 2026). Original GitHub issue: https://github.com/open-webui/open-webui/issues/23920 ## Bug Description Desktop clients (OpenCode Desktop, OnlyOffice plugin) receive `Decompression error: ZlibError` when streaming SSE from Claude/OpenAI models through Open WebUI's API proxy. The Web UI works fine. Related to: #23917 (Bug 1) ## Root Cause `aiohttp` sends `Accept-Encoding: gzip` to upstream APIs. When the upstream responds with `Content-Encoding: gzip`, aiohttp **auto-decompresses** the response body but **keeps the stale `Content-Encoding: gzip` header** (see [aiohttp#4462](https://github.com/aio-libs/aiohttp/issues/4462)). `openai.py` forwards all upstream headers verbatim via `headers=dict(r.headers)` at 4 `StreamingResponse` locations. The client receives `Content-Encoding: gzip` header with plain-text body, tries to decompress, and fails. ## Fix Strip encoding headers that become stale after aiohttp auto-decompression: ```python _STRIP_PROXY_HEADERS = frozenset({'Content-Encoding', 'Content-Length', 'Transfer-Encoding'}) def _clean_proxy_headers(raw_headers) -> dict: return {k: v for k, v in raw_headers.items() if k not in _STRIP_PROXY_HEADERS} ``` Applied at all 4 `StreamingResponse` locations in `openai.py`. ## Impact - **Web UI**: None (browser path doesn't use the OpenAI proxy for SSE) - **API clients**: All desktop/programmatic clients that honor `Content-Encoding` are fixed ## File `backend/open_webui/routers/openai.py` ## Reproduction ```bash curl --compressed -sN -H "Authorization: Bearer $KEY" \ -d '{"model":"claude-model","messages":[{"role":"user","content":"hi"}],"stream":true}' \ http://localhost:3000/api/chat/completions # Result: ZlibError or garbled output ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#35636