Response leak in SSE handlers #1450
Description
I found a resource leak in the streamable HTTP client. When SSE streaming fails with an exception, the HTTP response isn't closed.
Location:
src/mcp/client/streamable_http.py:
_handle_sse_response(line 336)_handle_resumption_request(line 251)
The Issue:
python
async def _handle_sse_response(self, response: httpx.Response, ...):
try:
event_source = EventSource(response)
async for sse in event_source.aiter_sse():
if is_complete:
await response.aclose() # Only closed here
break
except Exception as e:
await ctx.read_stream_writer.send(e)
# response leaked!
If the SSE iteration raises an exception (malformed JSON, network error, etc.), the response is never closed.
Impact:
Connection pool gets exhausted in long-running clients, eventually causing new requests to hang or fail.
Fix:
try:
...
except Exception as e:
...
finally:
await response.aclose()
Both methods need this fix.
Env:
Python SDK version: 1.1.2 (or main branch)
Python: 3.12
Transport: StreamableHTTP
Activity
maxisbey commentedon Oct 9, 2025
Thanks for the report! Please provide a minimal reproducible example code snippet we can run to confirm the issue
certainly-param commentedon Oct 17, 2025
Hey!
I've created a PR with the reproduction tests you requested.
The tests confirm the resource leak - when SSE streaming fails with exceptions, the HTTP response doesn't get closed properly in both _handle_sse_response and _handle_resumption_request.
I added two test files:
You can run the tests to see the problem in action. The fix is straightforward - just need finally blocks to ensure response.aclose() always gets called.
PR: #1490
Add tests for resource leak in streamable_http SSE handlers
felixweinberger commentedon Oct 17, 2025
Hi @certainly-param thank you for the detailed test case demonstration!