encode/httpx · error · StreamClosed
Attempted to read or stream content, but the stream has…
Error message
Attempted to read or stream content, but the stream has been closed.
What it means
Raised as `StreamClosed` by sync `iter_raw()` when `is_closed` is True. Once a response stream is closed (explicitly via `.close()` or implicitly by being read to completion), further reads are rejected because the connection has been released back to the pool.
Solutions
- Perform all reads inside the `with client.stream(...) as r:` block.
- Call `response.read()` once inside the context and then use `response.content` outside it.
- If you need the body later, switch to a non-streaming `client.get()` which reads and keeps the body.
- Track a `closed` flag in your own code to avoid touching a closed response.
Example fix
// before
with client.stream('GET', url) as r:
pass
for c in r.iter_bytes(): # StreamClosed
...
// after
with client.stream('GET', url) as r:
r.read()
print(r.text) # buffered, safe outside the block Defensive patterns
Strategy: validation
Validate before calling
def is_open(resp: httpx.Response) -> bool:
return not resp.is_closed Type guard
import httpx
def stream_is_open(resp: httpx.Response) -> bool:
return not resp.is_closed Try / catch
try:
for chunk in response.iter_bytes():
...
except httpx.StreamClosed:
# re-issue the request for a fresh stream
response = client.get(response.request.url, stream=True) Prevention
- Consume the body fully inside the with client.stream(...) block.
- Call response.read() inside the block, use response.content outside.
- Track a closed flag in long-lived consumers.
When it happens
Trigger: Calling `response.iter_raw()` / `iter_bytes()` after `response.close()`, or after the `with client.stream(...)` context exited (which closes the response).
Common situations: Stepping outside a `with client.stream(...) as r:` block and then trying to read the body; calling `.read()` inside the block, exiting, then iterating; double close from a finally block.
Related errors
- Attempted to access streaming response content, without…
- Attempted to read or stream some content, but the content…
- Attempted to call a sync close on an async stream.
- Attempted to call a sync iterator on an async stream.
- Attempted to call an async close on a sync stream.
AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04).
Data as JSON: /api/errors/cfb4f23ef2b47af7.
Report an issue: GitHub.
Appendix: source
Thrown at httpx/_models.py:942
yield chunk
def iter_lines(self) -> typing.Iterator[str]:
decoder = LineDecoder()
with request_context(request=self._request):
for text in self.iter_text():
for line in decoder.decode(text):
yield line
for line in decoder.flush():
yield line
def iter_raw(self, chunk_size: int | None = None) -> typing.Iterator[bytes]:
"""
A byte-iterator over the raw response content.
"""
if self.is_stream_consumed:
raise StreamConsumed()
if self.is_closed:
raise StreamClosed()
if not isinstance(self.stream, SyncByteStream):
raise RuntimeError("Attempted to call a sync iterator on an async stream.")
self.is_stream_consumed = True
self._num_bytes_downloaded = 0
chunker = ByteChunker(chunk_size=chunk_size)
with request_context(request=self._request):
for raw_stream_bytes in self.stream:
self._num_bytes_downloaded += len(raw_stream_bytes)
for chunk in chunker.decode(raw_stream_bytes):
yield chunk
for chunk in chunker.flush():
yield chunk
self.close()
View on GitHub (pinned to b5addb64f0)