encode/httpx · error · RuntimeError
Cannot reopen a client instance, once it has been closed.
Error message
Cannot reopen a client instance, once it has been closed.
What it means
Raised as RuntimeError by sync Client.__enter__ when self._state == ClientState.CLOSED. After __exit__/close() the client is permanently closed and cannot be reopened.
Source
Thrown at httpx/_client.py:1283
Close transport and proxies.
"""
if self._state != ClientState.CLOSED:
self._state = ClientState.CLOSED
self._transport.close()
for transport in self._mounts.values():
if transport is not None:
transport.close()
def __enter__(self: T) -> T:
if self._state != ClientState.UNOPENED:
msg = {
ClientState.OPENED: "Cannot open a client instance more than once.",
ClientState.CLOSED: (
"Cannot reopen a client instance, once it has been closed."
),
}[self._state]
raise RuntimeError(msg)
self._state = ClientState.OPENED
self._transport.__enter__()
for transport in self._mounts.values():
if transport is not None:
transport.__enter__()
return self
def __exit__(
self,
exc_type: type[BaseException] | None = None,
exc_value: BaseException | None = None,
traceback: TracebackType | None = None,
) -> None:
self._state = ClientState.CLOSED
self._transport.__exit__(exc_type, exc_value, traceback)View on GitHub (pinned to b5addb64f0)
Solutions
- Construct a new httpx.Client for each fresh usage scope.
- Keep one long-lived client and use it without repeatedly entering/exiting context managers.
Example fix
// before
with client:
client.get(url)
with client: # RuntimeError: cannot reopen
client.get(url)
// after
with httpx.Client() as client:
client.get(url) Defensive patterns
Strategy: validation
Validate before calling
import httpx
if client.is_closed:
raise RuntimeError("client already closed; create a new httpx.Client")
with client:
client.get(url) Type guard
import httpx
def is_reusable(client: httpx.Client) -> bool:
return not client.is_closed Try / catch
try:
with client:
client.get(url)
except RuntimeError as exc:
if "once it has been closed" in str(exc):
with httpx.Client(...) as client:
client.get(url)
else:
raise Prevention
- Treat a closed client as disposable; always create a new one.
- Avoid reusing a client across separate with-blocks.
- Check client.is_closed before attempting to reopen.
When it happens
Trigger: Re-entering a 'with client:' block after the previous one exited, or calling client.__enter__() after client.close().
Common situations: Storing a client and trying to reuse it as a context manager after it was already used and closed; retry logic that reopens a closed client.
Related errors
- Cannot open a client instance more than once.
- Cannot send a request, as the client has been closed.
- Exceeded maximum allowed redirects.
- Attempted to send an async request with a sync Client instan
- Attempted to read or stream content, but the stream has been
AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04).
Data as JSON: /data/errors/28c4027f14724dc0.json.
Report an issue: GitHub.