-
Notifications
You must be signed in to change notification settings - Fork 613
[BUG]: gunicorn workers crash with SIGSEGV on macOS when running make serve #2837
Copy link
Copy link
Closed
Copy link
Labels
bugSomething isn't workingSomething isn't workingtriageIssues / Features awaiting triageIssues / Features awaiting triage
Milestone
Description
Description
When running make serve on macOS, gunicorn workers repeatedly crash with SIGSEGV (segmentation fault) errors:
[2026-02-11 14:07:39 +0530] [55715] [WARNING] Worker (pid:55773) was sent SIGSEGV!
[2026-02-11 14:07:39 +0530] [55715] [INFO] Worker child exit (pid: 55773)
Workers spawn and immediately crash in a continuous loop, making the server unusable.
Environment
- OS: macOS (Darwin)
- Python: 3.12.12
- Gunicorn: 24.1.1
- Worker Class: uvicorn.workers.UvicornWorker
- Command:
make serve(which runs gunicorn with--preload)
Root Cause
macOS has strict fork-safety requirements. When gunicorn uses the --preload flag (which loads the application in the master process before forking workers), any Python libraries that interact with:
- CoreFoundation framework
- Objective-C runtime
- Asyncio event loops
- SQLAlchemy connections
...will be in an invalid state in the forked worker processes, causing immediate SIGSEGV crashes.
The specific chain of events:
run-gunicorn.shsetsGUNICORN_PRELOAD_APP=trueby default- gunicorn loads
gunicorn.config.pywhich importsmcpgateway.config mcpgateway.configimports SQLAlchemy and other async libraries- gunicorn forks worker processes
- Workers inherit invalid/uninitialized state from the master process
- Workers crash with SIGSEGV when trying to use SQLAlchemy/asyncio
References
- gunicorn issue #2761 - Fork can eventually cause sigsegv on macos
- Python bug #13829 - os.fork issues on macOS
Workarounds (Before Fix)
Users could work around this by:
- Using
make devinstead (runs uvicorn directly without forking) - Setting
GUNICORN_PRELOAD_APP=falseenvironment variable - Using Granian:
make serve-granian
Solution
Disable --preload by default on macOS:
- gunicorn.config.py: Set
preload_app = platform.system() != "Darwin" - run-gunicorn.sh: Check for Darwin and set
GUNICORN_PRELOAD_APP=falseby default
This ensures workers import the application code AFTER forking, avoiding the fork-safety issues.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingtriageIssues / Features awaiting triageIssues / Features awaiting triage