GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — asyncio proactor udp transport stops responding after send to port that isn't listening due to ConnectionResetError from WSARecvFrom · Issue #127057 · python/cpython

asyncio proactor udp transport stops responding after send to port that isn't listening due to ConnectionResetError from WSARecvFrom #127057

New issue
Copy link
New issue
Copy link
Closed
Closed
asyncio proactor udp transport stops responding after send to port that isn't listening due to ConnectionResetError from WSARecvFrom#127057
Copy link
Labels
topic-asynciotype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@bugale
bugale
opened on Nov 20, 2024
Issue body actions

Bug report

Bug description:

I face a similar issue to #91227 , although instead of the error being thrown from the GetOverlappedResult, I get a ConnectionResetError thrown directly from the WSARecvFrom call.

I am not quite sure what causes Windows to decide to throw the error from WSARecvFrom rather than from the respective GetOverlappedResult, but it appears to have something to do with timings and/or number of times an ICMP unreachable has been sent.

I haven't put a log of effort to investigate, but I am able to reproduce it 100% of the times on my machine using this code:

import asyncio
import time
import socket


class Protocol(asyncio.DatagramProtocol):
    def connection_made(self, transport):
        self.transport = transport

    def datagram_received(self, data, addr):
        print(f'Received {data}')
        time.sleep(1)
        self.transport.sendto(b'test', ('127.0.0.1', 51346))


def send_data():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    for i in range(100):
        print(f'Sending {str(i)}')
        s.sendto(str(i).encode(), ('127.0.0.1', 1337))
        time.sleep(1)
    s.close()


async def main():
    loop = asyncio.get_running_loop()
    transport, _ = await loop.create_datagram_endpoint(Protocol, local_addr=('127.0.0.1', 1337))
    await asyncio.get_running_loop().run_in_executor(None, send_data)
    transport.close()


asyncio.run(main())

I usually get something like this output:

Sending 0
Received b'0'
Sending 1
Received b'1'
Sending 2
Received b'2'
Sending 3
Sending 4
Sending 5
Sending 6
Sending 7

(i.e. after ~3 successful receives, the server stops receiving data).

While debugging it, I was able to see that the call to ov.WSARecvFrom(conn.fileno(), nbytes, flags) in windows_event.py throws a ConnectionResetError at some point, which is caught in _loop_writing in proactor_events.py, causing it to basically stop its receiving loop.

An easy fix would be to retry the call to ov.WSARecvFrom(conn.fileno(), nbytes, flags) on ConnectionResetError. It seems to work after 2 retries, though I couldn't find a documentation that guarantees this behavior.
Something like this works for me:

    def recvfrom(self, conn, nbytes, flags=0):
        self._register_with_iocp(conn)
-        ov = _overlapped.Overlapped(NULL)
        try:
+            for _ in range(10):
+                try:
+                    ov = _overlapped.Overlapped(NULL)
-            ov.WSARecvFrom(conn.fileno(), nbytes, flags)
+                    ov.WSARecvFrom(conn.fileno(), nbytes, flags)
+                    break
+                except ConnectionResetError:
+                    pass
        except BrokenPipeError:
            return self._result((b'', None))

        return self._register(ov, conn, partial(self._finish_recvfrom,
                                                empty_result=b''))

I could open a PR with such a change, though I am not sure how it should be tested, as I wasn't able to reproduce the issue without ugly and non-deterministic sleeps.

CPython versions tested on:

3.13

Operating systems tested on:

Windows

Linked PRs

  • gh-127057: Re-arm proactor datagram read loop after a recoverable OSError #156726
  • [3.15] gh-127057: reschedule proactor datagram read loop after ConnectionResetError (GH-156726) #156976
  • [3.14] gh-127057: reschedule proactor datagram read loop after ConnectionResetError (GH-156726) #156977
  • [3.13] gh-127057: reschedule proactor datagram read loop after ConnectionResetError (GH-156726) #156978
Reacted by David Rapan

Activity

  1. bugale
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Nov 20, 2024
  2. AlexWaygood
    added
    topic-asyncio
    on Nov 20, 2024
  3. github-project-automation
    added this to asyncioon Nov 20, 2024
  4. github-project-automation
    moved this to Todo in asyncioon Nov 20, 2024
  5. graingert
    added 3 commits that reference this issue on Aug 31, 2026

    pythongh-127057: Re-arm proactor datagram read loop after a recoverab…

    3c2e804

    pythongh-127057: Re-arm proactor datagram read loop after a recoverab…

    e45ba5a

    pythongh-127057: Re-arm proactor datagram read loop after a recoverab…

    eb09595
  6. kumaraditya303
    added 2 commits that reference this issue on Sep 5, 2026

    pythongh-127057: Fix proactor datagram transport going silent after C…

    d2ccd45

    gh-127057: reschedule proactor datagram read loop after ConnectionRes…

    0ea2971
  7. kumaraditya303
    closed this as completedon Sep 5, 2026
  8. github-project-automation
    moved this from Todo to Done in asyncioon Sep 5, 2026
  9. kumaraditya303
    added 2 commits that reference this issue on Sep 5, 2026

    [3.14] gh-127057: reschedule proactor datagram read loop after Connec…

    9e97d9f

    [3.13] gh-127057: reschedule proactor datagram read loop after Connec…

    ffa12f7
  10. hugovk
    added a commit that references this issue on Sep 5, 2026

    [3.15] gh-127057: reschedule proactor datagram read loop after Connec…

    4387744
  11. clin1234
    added a commit that references this issue on Sep 12, 2026

    pythongh-127057: reschedule proactor datagram read loop after Connect…

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic-asynciotype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    • asyncio
      Status
      Done
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.