Jump to solution
Verify

The Fix

Upgrade to version 0.12.0 or later.

Based on closed Kludex/uvicorn issue #684 · PR/commit linked

Production note: This usually shows up under retries/timeouts. Treat it as a side-effect risk until you can verify behavior with a canary + real traffic.

Jump to Verify Open PR/Commit
@@ -62,7 +62,8 @@ def startup(self): def restart(self): self.mtimes = {} - os.kill(self.process.pid, signal.SIGTERM) + + self.process.terminate()
repro.py
INFO: Application startup complete. INFO: <Server sockets=[<socket.socket fd=592, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('127.0.0.1', 8000)>]> is serving WARNING: Detected file change in 'app\fast.py'. Reloading... 2020-05-28 03:23:58.519 | DEBUG | app.log:setup_logger:24 - setup logger 2020-05-28 03:23:58.748 | DEBUG | app.middlewares.sentry:setup_sentry:14 - setup sentry WARNING: Executing <Task finished coro=<Server.serve() done, defined at C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py:384> exception=NameError("name 'a' is not defined") created at C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\asyncio\base_events.py:566> took 0.782 seconds Process SpawnProcess-2: Traceback (most recent call last): File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\multiprocessing\process.py", line 297, in _bootstrap self.run() File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\multiprocessing\process.py", line 99, in run self._target(*self._args, **self._kwargs) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\subprocess.py", line 62, in subprocess_started target(sockets=sockets) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py", line 382, in run loop.run_until_complete(self.serve(sockets=sockets)) File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\asyncio\base_events.py", line 587, in run_until_complete return future.result() File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py", line 389, in serve config.load() File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\config.py", line 288, in load self.loaded_app = import_from_string(self.app) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\importer.py", line 20, in import_from_string module = importlib.import_module(module_str) File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\importlib\__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1006, in _gcd_import File "<frozen importlib._bootstrap>", line 983, in _find_and_load File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 677, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 728, in exec_module File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed File ".\app\fast.py", line 111, in <module> a NameError: name 'a' is not defined WARNING: Detected file change in 'app\fast.py'. Reloading... Traceback (most recent call last): File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\__main__.py", line 4, in <module> uvicorn.main() File "C:\Users\Trim21\.venv\pol\lib\site-packages\click\core.py", line 829, in __call__ return self.main(*args, **kwargs) File "C:\Users\Trim21\.venv\pol\lib\site-packages\click\core.py", line 782, in main rv = self.invoke(ctx) File "C:\Users\Trim21\.venv\pol\lib\site-packages\click\core.py", line 1066, in invoke return ctx.invoke(self.callback, **ctx.params) File "C:\Users\Trim21\.venv\pol\lib\site-packages\click\core.py", line 610, in invoke return callback(*args, **kwargs) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py", line 331, in main run(* ... (truncated) ...
verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
fix.md
Option A — Upgrade to fixed release\nUpgrade to version 0.12.0 or later.\nWhen NOT to use: Do not use this fix if the application does not handle exceptions properly.\n\n

Why This Fix Works in Production

  • Trigger: WARNING: Detected file change in 'app\fast.py'. Reloading...
  • Mechanism: The child process exits abnormally after an exception, causing a PermissionError during reload
  • Why the fix works: Fixes a terminate error in Windows when an exception occurs during the reload process. (first fixed release: 0.12.0).
Production impact:
  • If left unfixed, retry loops can amplify load and turn a small outage into a cascade (thundering herd).

Why This Breaks in Prod

  • Shows up under Python 3.8 in real deployments (not just unit tests).
  • The child process exits abnormally after an exception, causing a PermissionError during reload
  • Surfaces as: INFO: Application startup complete.

Proof / Evidence

  • GitHub issue: #684
  • Fix PR: https://github.com/kludex/uvicorn/pull/744
  • First fixed release: 0.12.0
  • Reproduced locally: No (not executed)
  • Last verified: 2026-02-09
  • Confidence: 0.85
  • Did this fix it?: Yes (upstream fix exists)
  • Own content ratio: 0.19

Discussion

High-signal excerpts from the issue thread (symptoms, repros, edge-cases).

“can you check if you got the same on python 3.8, I kind of remember there was a multiprocessing python bug, cant find it now”
@euri10 · 2020-05-28 · source
“fixed by ignore OSError... I guess it's not a bug of multiprocessing, but the the process is not running. (sorry for my poor English)”
@trim21 · 2020-05-28 · source
“ok I just reproduced, it's when it's raising an exception, totally misread hte case sorry :)”
@euri10 · 2020-08-01 · source
“I checked the code, the problem here is that the child process exits abnormally after restarting. The main process did not detect this problem, so…”
@abersheeran · 2020-08-01 · source

Failure Signature (Search String)

  • WARNING: Detected file change in 'app\fast.py'. Reloading...

Error Message

Stack trace
error.txt
Error Message ------------- INFO: Application startup complete. INFO: <Server sockets=[<socket.socket fd=592, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('127.0.0.1', 8000)>]> is serving WARNING: Detected file change in 'app\fast.py'. Reloading... 2020-05-28 03:23:58.519 | DEBUG | app.log:setup_logger:24 - setup logger 2020-05-28 03:23:58.748 | DEBUG | app.middlewares.sentry:setup_sentry:14 - setup sentry WARNING: Executing <Task finished coro=<Server.serve() done, defined at C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py:384> exception=NameError("name 'a' is not defined") created at C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\asyncio\base_events.py:566> took 0.782 seconds Process SpawnProcess-2: Traceback (most recent call last): File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\multiprocessing\process.py", line 297, in _bootstrap self.run() File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\multiprocessing\process.py", line 99, in run self._target(*self._args, **self._kwargs) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\subprocess.py", line 62, in subprocess_started target(sockets=sockets) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py", line 382, in run loop.run_until_complete(self.serve(sockets=sockets)) File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\asyncio\base_events.py", ... (truncated) ...
Stack trace
error.txt
Error Message ------------- /home/lotso/PycharmProjects/uvicorn/venv/bin/python -m uvicorn app:app --reload INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [15496] using watchgod INFO: Started server process [15518] INFO: Waiting for application startup. INFO: ASGI 'lifespan' protocol appears unsupported. INFO: Application startup complete. WARNING: Detected file change in '['/home/lotso/PycharmProjects/uvicorn/app.py']'. Reloading... INFO: Shutting down INFO: Finished server process [15518] Process SpawnProcess-2: Traceback (most recent call last): File "/home/lotso/.asdf/installs/python/3.8.5/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap self.run() File "/home/lotso/.asdf/installs/python/3.8.5/lib/python3.8/multiprocessing/process.py", line 108, in run self._target(*self._args, **self._kwargs) File "./uvicorn/subprocess.py", line 62, in subprocess_started target(sockets=sockets) File "./uvicorn/main.py", line 390, in run loop.run_until_complete(self.serve(sockets=sockets)) File "uvloop/loop.pyx", line 1456, in uvloop.loop.Loop.run_until_complete File "./uvicorn/main.py", line 397, in serve config.load() File "./uvicorn/config.py", line 278, in load self.loaded_app = import_from_string(self.app) File "./uvicorn/importer.py", line 20, in import_from_string ... ... (truncated) ...

Minimal Reproduction

repro.py
INFO: Application startup complete. INFO: <Server sockets=[<socket.socket fd=592, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('127.0.0.1', 8000)>]> is serving WARNING: Detected file change in 'app\fast.py'. Reloading... 2020-05-28 03:23:58.519 | DEBUG | app.log:setup_logger:24 - setup logger 2020-05-28 03:23:58.748 | DEBUG | app.middlewares.sentry:setup_sentry:14 - setup sentry WARNING: Executing <Task finished coro=<Server.serve() done, defined at C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py:384> exception=NameError("name 'a' is not defined") created at C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\asyncio\base_events.py:566> took 0.782 seconds Process SpawnProcess-2: Traceback (most recent call last): File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\multiprocessing\process.py", line 297, in _bootstrap self.run() File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\multiprocessing\process.py", line 99, in run self._target(*self._args, **self._kwargs) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\subprocess.py", line 62, in subprocess_started target(sockets=sockets) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py", line 382, in run loop.run_until_complete(self.serve(sockets=sockets)) File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\asyncio\base_events.py", line 587, in run_until_complete return future.result() File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py", line 389, in serve config.load() File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\config.py", line 288, in load self.loaded_app = import_from_string(self.app) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\importer.py", line 20, in import_from_string module = importlib.import_module(module_str) File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\importlib\__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1006, in _gcd_import File "<frozen importlib._bootstrap>", line 983, in _find_and_load File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 677, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 728, in exec_module File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed File ".\app\fast.py", line 111, in <module> a NameError: name 'a' is not defined WARNING: Detected file change in 'app\fast.py'. Reloading... Traceback (most recent call last): File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "C:\Users\Trim21\scoop\apps\python37\3.7.7\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\__main__.py", line 4, in <module> uvicorn.main() File "C:\Users\Trim21\.venv\pol\lib\site-packages\click\core.py", line 829, in __call__ return self.main(*args, **kwargs) File "C:\Users\Trim21\.venv\pol\lib\site-packages\click\core.py", line 782, in main rv = self.invoke(ctx) File "C:\Users\Trim21\.venv\pol\lib\site-packages\click\core.py", line 1066, in invoke return ctx.invoke(self.callback, **ctx.params) File "C:\Users\Trim21\.venv\pol\lib\site-packages\click\core.py", line 610, in invoke return callback(*args, **kwargs) File "C:\Users\Trim21\.venv\pol\lib\site-packages\uvicorn\main.py", line 331, in main run(* ... (truncated) ...

Environment

  • Python: 3.8

What Broke

Uvicorn fails to restart after an exception, leading to application downtime.

Why It Broke

The child process exits abnormally after an exception, causing a PermissionError during reload

Fix Options (Details)

Option A — Upgrade to fixed release Safe default (recommended)

Upgrade to version 0.12.0 or later.

When NOT to use: Do not use this fix if the application does not handle exceptions properly.

Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.

Fix reference: https://github.com/kludex/uvicorn/pull/744

First fixed release: 0.12.0

Last verified: 2026-02-09. Validate in your environment.

Get updates

We publish verified fixes weekly. No spam.

Subscribe

When NOT to Use This Fix

  • Do not use this fix if the application does not handle exceptions properly.

Verify Fix

verify
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.

Did This Fix Work in Your Case?

Quick signal helps us prioritize which fixes to verify and improve.

Prevention

  • Make timeouts explicit and test them (unit + integration) to avoid silent behavior changes.
  • Instrument retries (attempt count + reason) and alert on spikes to catch dependency slowdowns.

Version Compatibility Table

VersionStatus
0.12.0 Fixed

Related Issues

No related fixes found.

Sources

We don’t republish the full GitHub discussion text. Use the links above for context.