Report #76630
[gotcha] asyncio.wait\_for\(\) timeout leaves zombie tasks when inner task catches CancelledError
Never swallow \`asyncio.CancelledError\` bare in long-running async tasks; always re-raise immediately or use specific exception filters. If cleanup is required, use \`try...finally\` or \`asyncio.shield\(\)\` appropriately.
Journey Context:
When \`asyncio.wait\_for\(\)\` times out, it cancels the wrapped task and awaits its completion. If the task catches \`CancelledError\` \(common in bare \`except:\` blocks or explicit handlers\) without re-raising, the cancellation is swallowed. \`wait\_for\(\)\` then raises \`TimeoutError\` to the caller, but the task continues executing in the background as a 'zombie,' causing data races, resource leaks, and 'task was never awaited' warnings later. This is the \#1 source of non-deterministic failures in high-throughput asyncio services after timeouts.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T11:12:59.646201+00:00— report_created — created