This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Title: asyncio and ssl: ResourceWarning: unclosed transport
Type: Stage: resolved
Components: asyncio Versions: Python 3.11
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: asvetlov, kumaraditya, mdk, yselivanov
Priority: normal Keywords:

Created on 2022-01-09 15:04 by mdk, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (8)
msg410156 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2022-01-09 15:04
Originally opened at:


    import asyncio

    class DumbProtocol(asyncio.Protocol):
        def connection_made(self, transport):
            print("Connection made")
            self.transport = transport

        def data_received(self, data):
            print("Data received: {!r}".format(data))

    async def main():
        loop = asyncio.get_running_loop()

        for i in range(2):
            _, _ = await loop.create_connection(DumbProtocol, "", 443, ssl=True)
        while True:
            print("Waiting for the server to close the connection...")
            await asyncio.sleep(10)

Using this reproducer I get a ResourceWarning:

    Data received: b"HTTP/1.0 408 Request Time-out\r\nCache-Control: no-cache\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n<html><body><h1>408 Request Time-out</h1>\nYour browser didn't send a complete request in time.\n</body></html>\n\n"
    /usr/lib/python3.9/asyncio/ ResourceWarning: unclosed transport <asyncio.sslproto._SSLProtocolTransport object at 0x7f9328214050>
      _warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
    Object allocated at (most recent call last):
      File "/usr/lib/python3.9/asyncio/", lineno 445
        self._app_transport = _SSLProtocolTransport(self._loop, self)

I can also reproduce it on current master.
msg410193 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2022-01-10 09:02
Related to:
msg410212 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2022-01-10 13:31
Feel like SSLProtocol's connection_lost should "bubble up" the info by calling SSLProtocolTransport's close.

But I'm no familiar with this stack.
msg410416 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2022-01-12 17:17
I don't know if it's related but _SSLPipe._shutdown_cb looks never called, in:

    self._sslobj = None
    self._state = _UNWRAPPED

    if self._shutdown_cb:

the unwrap() call seems to always raise (The operation did not complete (read) (_ssl.c:2756)), thus never calling `self._shutdown_cb()`.
msg410495 - (view) Author: Julien Palard (mdk) * (Python committer) Date: 2022-01-13 16:17
Probably related to and
msg413300 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2022-02-15 19:33
Please check against the latest master.
It has rewritten SSL protocol implementation borrowed from uvloop.
See #44011 for details
msg414103 - (view) Author: Kumar Aditya (kumaraditya) * (Python triager) Date: 2022-02-26 13:33
@asvetlov I tested it on main branch and indeed it is fixed on main branch with
msg414109 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2022-02-26 14:44
Date User Action Args
2022-04-11 14:59:54adminsetgithub: 90476
2022-02-26 14:45:10asvetlovsetstatus: open -> closed
stage: resolved
resolution: fixed
versions: - Python 3.7, Python 3.8, Python 3.9, Python 3.10
2022-02-26 14:44:57asvetlovsetmessages: + msg414109
2022-02-26 13:33:34kumaradityasetmessages: + msg414103
2022-02-15 19:33:37asvetlovsetmessages: + msg413300
2022-01-13 16:17:16mdksetmessages: + msg410495
2022-01-12 17:17:40mdksetmessages: + msg410416
2022-01-10 13:31:21mdksetmessages: + msg410212
2022-01-10 09:02:20mdksetmessages: + msg410193
2022-01-10 07:08:09kumaradityasetnosy: + kumaraditya
2022-01-09 15:04:53mdkcreate