Skip to content

Fix connect_tcp() leaking a connected socket on outer cancellation - #1367

Merged
agronholm merged 4 commits into
agronholm:masterfrom
charan-rathore:fix/connect-tcp-cancel-socket-leak
Oct 10, 2026
Merged

agronholm merged 4 commits into
agronholm:masterfrom
charan-rathore:fix/connect-tcp-cancel-socket-leak

Conversation

@charan-rathore

Copy link
Copy Markdown
Contributor

NOTE Erasing or replacing the contents of this template will result in your pull
request being summarily closed without consideration!

Changes

Fixes #1364.

When connect_tcp() is called inside a cancel scope that gets cancelled after one of the connection attempts has succeeded but before the internal task group exits, the winning SocketStream was dropped without being closed, leaking a connected socket. This adds a BaseException handler that forcefully closes the connected stream before re-raising.

Checklist

If this is a user-facing code change, like a bugfix or a new feature, please ensure that
you've fulfilled the following conditions (where applicable):

  • You've added tests (in tests/) which would fail without your patch
  • You've updated the documentation (in docs/), in case of behavior changes or new
    features
  • You've added a new changelog entry (in docs/versionhistory.rst).

If this is a trivial change, like a typo fix or a code reformatting, then you can ignore
these instructions.

Updating the changelog

If there are no entries after the last release, use **UNRELEASED** as the version.
If, say, your patch fixes issue #123, the entry should look like this:

- Fix big bad boo-boo in task groups
  (`#123 <https://github.com/agronholm/anyio/issues/123>`_; PR by @yourgithubaccount)

If there's no issue linked, just link to your pull request instead by updating the
changelog after you've created the PR.


Testing notes: the new test (test_connect_tcp_closes_winner_on_outer_cancellation) fails without the patch and passes with it on asyncio, asyncio+uvloop and Trio backends. Full pytest tests/ run with the patch: 4253 passed, 6 failed; all 6 failures (TLS certificate check variants in test_sockets.py) also fail identically on unmodified upstream source in this environment, so they are unrelated to this change.

Fixes #1364. When an enclosing cancel scope was cancelled after a
connection attempt succeeded but before the task group exited, the
connected stream was dropped without being closed. Close it forcefully
on the BaseException path.
@charan-rathore

Copy link
Copy Markdown
Contributor Author

Friendly bump on this when you have a moment. CI is green, and I'm happy to adjust anything you'd like changed.

@agronholm

Copy link
Copy Markdown
Owner

Why did you close the PR?

@charan-rathore charan-rathore reopened this Oct 4, 2026
@charan-rathore

Copy link
Copy Markdown
Contributor Author

Sorry, this was closed by mistake, reopening.

@agronholm

Copy link
Copy Markdown
Owner

I have tons of PRs to review and a change to the changelog update procedure in the works, so I don't know when I'll get around to this one. Hopefully not too long.

@agronholm agronholm left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@agronholm
agronholm merged commit c7b992c into agronholm:master Oct 10, 2026
20 checks passed
charan-rathore added a commit to charan-rathore/charan-rathore that referenced this pull request Oct 10, 2026
@charan-rathore
charan-rathore deleted the fix/connect-tcp-cancel-socket-leak branch October 11, 2026 04:43
@erlend-aasland

Copy link
Copy Markdown
Contributor

It would be lovely to see a release with this fix in it; is there a release scheduled any time soon?

Thanks for all your work on anyio! 🙏

@agronholm

Copy link
Copy Markdown
Owner

Yes. Check the milestone for remaining PRs/issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

connect_tcp() leaks a connected socket when an enclosing scope is cancelled after the connect succeeds

3 participants