aiohttp Unclosed client session (tested)
aiohttp warns Unclosed client session when a ClientSession is garbage-collected without being closed. Use async with aiohttp.ClientSession() or await session.close(), and reuse one session.
1. Reproduce it
import asyncio, gc, aiohttp
async def main():
s = aiohttp.ClientSession() # never closed
print("closed?", s.closed)
asyncio.run(main())
gc.collect()
Output:
closed? False
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f6be46592b0>
aiohttp prints Unclosed client session when a ClientSession that was never closed is garbage-collected. The session owns a connection pool, so the warning means sockets may have been left open.
2. Fix: async with (or await close())
import asyncio, aiohttp
async def main():
async with aiohttp.ClientSession() as s:
pass
print("closed?", s.closed)
asyncio.run(main())
print("no warning")
Output:
closed? True
no warning
Use async with aiohttp.ClientSession() as s:, or call await s.close() in a finally block. Create one session and reuse it for many requests rather than one per request; a long-lived session belongs to your app's startup/shutdown (e.g. a FastAPI lifespan), closed on shutdown.
3. Creating a session outside the event loop
import aiohttp
s = aiohttp.ClientSession() # created outside a running loop
Output:
Traceback (most recent call last):
File "/w/b3.py", line 2, in <module>
s = aiohttp.ClientSession() # created outside a running loop
File "/usr/local/lib/python3.14/site-packages/aiohttp/client.py", line 374, in __init__
loop = loop or asyncio.get_running_loop()
~~~~~~~~~~~~~~~~~~~~~~~~^^
RuntimeError: no running event loop
aiohttp 3.14 refuses to create a session at import time or module level: it needs a running loop. Create it inside an async function.
Related: asyncio Task exception was never retrieved, asyncio Event loop is closed.
Frequently asked questions
What causes aiohttp Unclosed client session?
A ClientSession was garbage-collected without close(). Use async with or await session.close().
Can I create an aiohttp ClientSession at module level?
Not in aiohttp 3.14.5: it raises RuntimeError: no running event loop. Create it inside an async function.
Written with AI assistance. Measured on 2026-10-23 with aiohttp 3.14.5 and Python 3.14.7 (python:3-alpine in Docker). Each block was run verbatim and the output pasted unedited. PlainHeaders is our extension; Python and aiohttp are free.