Skip to content

asyncio SSL transport ignores ssl_shutdown_timeout after the peer sends EOF #160520

Description

@gpshead

Bug report

Bug description:

ssl_shutdown_timeout stops applying to an asyncio SSL transport once the peer has sent EOF. SSLProtocol._on_shutdown_complete() cancels the shutdown timer (or never starts one if the EOF arrived before close()) and then calls the non-aborting close() of the underlying transport, which waits for its write buffer to drain. If the peer does not read, close() / wait_closed() never finish, while the same peer without the half-close is aborted after the timeout.

import asyncio, socket, ssl
from test.support import findfile

CERT = findfile('keycert.pem', subdir='certdata')

async def handler(reader, writer):
    await reader.readline()
    writer.write(bytes(16 << 20))
    writer.close()
    try:
        await asyncio.wait_for(writer.wait_closed(), 5)
    except TimeoutError as e:
        print('server:', repr(e) if e.args else 'still open after 5 s')
        writer.transport.abort()

def client(port, half_close):
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    s = ctx.wrap_socket(socket.create_connection(('127.0.0.1', port)))
    s.sendall(b'x\n')
    if half_close:
        s.shutdown(socket.SHUT_WR)
    return s  # never read

async def main():
    sctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    sctx.load_cert_chain(CERT)
    server = await asyncio.start_server(
        handler, '127.0.0.1', 0, ssl=sctx, ssl_shutdown_timeout=1)
    port = server.sockets[0].getsockname()[1]
    for half_close in (False, True):
        print('peer half-closes:', half_close)
        s = await asyncio.to_thread(client, port, half_close)
        await asyncio.sleep(6)
        s.close()
    server.close()
    await server.wait_closed()

asyncio.run(main())

Output:

peer half-closes: False
server: TimeoutError('SSL shutdown timed out')
peer half-closes: True
server: still open after 5 s

Expected: both connections are aborted with TimeoutError('SSL shutdown timed out') after 1 second. The code is the same on 3.14 and 3.15.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Activity

  1. self-assigned this
    on Oct 23, 2026
  2. added
    type-bugAn unexpected behavior, bug, or error
    stdlibStandard Library Python modules in the Lib/ directory
    on Oct 23, 2026
  3. added a commit that references this issue on Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

stdlibStandard Library Python modules in the Lib/ directorytopic-SSLtopic-asynciotype-bugAn unexpected behavior, bug, or error

Projects

  • Status
    Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions