Jump to solution
Verify

The Fix

Upgrade to version 0.13.3 or later.

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

Production note: Most teams hit this during upgrades or environment changes. Roll out with a canary and smoke critical endpoints (health, OpenAPI/docs) before 100%.

Jump to Verify Open PR/Commit
@@ -1,5 +1,6 @@ import asyncio import logging +import signal from gunicorn.workers.base import Worker
repro.py
import logging from starlette.applications import Starlette from starlette.responses import JSONResponse from starlette.routing import Route logging.basicConfig(level=logging.DEBUG, filename='./log.txt') logger = logging.getLogger(__name__) async def some_startup_task(): logger.info("startup") async def some_shutdown_task(): logger.info("shutdown") async def homepage(request): logger.debug("homepage()") return JSONResponse({'hello': 'world'}) app = Starlette(debug=False, routes=[Route('/', homepage)], on_startup=[some_startup_task], on_shutdown=[some_shutdown_task])
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.13.3 or later.\nWhen NOT to use: Do not use if it changes public behavior or if the failure cannot be reproduced.\n\n

Why This Fix Works in Production

  • Trigger: this 10 times does not log to any access log.
  • Mechanism: UvicornWorker does not reset signals correctly, causing issues with log rotation
  • Why the fix works: Fix resetting signals in Gunicorn UvicornWorker to ensure subprocesses capture the correct return code. (first fixed release: 0.13.3).
Production impact:
  • If left unfixed, the same config can fail only in production (env differences), causing startup failures or partial feature outages.

Why This Breaks in Prod

  • Shows up under Python 3.8.3 in real deployments (not just unit tests).
  • UvicornWorker does not reset signals correctly, causing issues with log rotation
  • Production symptom (often without a traceback): -rw-r--r--. 1 root root 5402 Dec 16 17:08 error.log

Proof / Evidence

  • GitHub issue: #896
  • Fix PR: https://github.com/encode/uvicorn/pull/895
  • First fixed release: 0.13.3
  • 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.57

Verified Execution

We executed the runnable minimal repro in a temporary environment and captured exit codes + logs.

  • Status: PASS
  • Ran: 2026-02-11T16:52:29Z
  • Package: uvicorn
  • Fixed: 0.13.3
  • Mode: fixed_only
  • Outcome: ok
Logs
affected (exit=None)
fixed (exit=0)

Discussion

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

“> How can we reopen a log file without restarting worker processes for log rotation? no idea, someone more familiar with gunicorn internals might have…”
@euri10 · 2021-01-12 · source
“logrotate copytruncate option works for me!”
@yinkh · 2020-12-16 · source
“But use copytruncate instead of create for logrotate, has the risk of lost log record, hope someone can find the real reason cause this issue!”
@yinkh · 2020-12-16 · source
“In gunicorn(version 20.0.4 ), has some code related to USR1 singles, here is the key code: venv/Lib/site-packages/gunicorn/workers/base.py line 165 venv/Lib/site-packages/gunicorn/glogging.py line 352”
@yinkh · 2021-01-01 · source

Failure Signature (Search String)

  • this 10 times does not log to any access log.
Copy-friendly signature
signature.txt
Failure Signature ----------------- -rw-r--r--. 1 root root 5402 Dec 16 17:08 error.log this 10 times does not log to any access log.

Error Message

Signature-only (no traceback captured)
error.txt
Error Message ------------- -rw-r--r--. 1 root root 5402 Dec 16 17:08 error.log this 10 times does not log to any access log.

Minimal Reproduction

repro.py
import logging from starlette.applications import Starlette from starlette.responses import JSONResponse from starlette.routing import Route logging.basicConfig(level=logging.DEBUG, filename='./log.txt') logger = logging.getLogger(__name__) async def some_startup_task(): logger.info("startup") async def some_shutdown_task(): logger.info("shutdown") async def homepage(request): logger.debug("homepage()") return JSONResponse({'hello': 'world'}) app = Starlette(debug=False, routes=[Route('/', homepage)], on_startup=[some_startup_task], on_shutdown=[some_shutdown_task])

Environment

  • Python: 3.8.3

What Broke

Access logs are not written after logrotate is executed, leading to missing log entries.

Why It Broke

UvicornWorker does not reset signals correctly, causing issues with log rotation

Fix Options (Details)

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

Upgrade to version 0.13.3 or later.

When NOT to use: Do not use if it changes public behavior or if the failure cannot be reproduced.

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

Fix reference: https://github.com/encode/uvicorn/pull/895

First fixed release: 0.13.3

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 if it changes public behavior or if the failure cannot be reproduced.

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

  • Capture the exact failing error string in logs and tests so you can reproduce via a minimal script.
  • Pin production dependencies and upgrade only with a reproducible test that hits the failing path.

Version Compatibility Table

VersionStatus
0.13.3 Fixed

Related Issues

No related fixes found.

Sources

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