pytest-xdist "worker ... crashed" / "Replacing crashed worker" in CI
With pytest -n (xdist), tests run in worker subprocesses. When a worker dies hard - a native segfault, an OOM kill, or a test calling os._exit - xdist reports the worker crashed and may replace it, often losing the test that caused it.
What this error means
The run prints [gw0] node down: Not properly terminated and replacing crashed worker gw0, or worker gw1 crashed while running. The failure can be flaky and hard to attribute because the offending test’s output is lost with the worker.
[gw0] node down: Not properly terminated
replacing crashed worker gw0
INTERNALERROR> ... worker 'gw0' crashed while running
'tests/test_native.py::test_segfault'Common causes
A native crash (segfault) in a C extension
A C/Rust extension or ctypes call segfaults the worker process. Python cannot catch it, so xdist sees the worker die.
Out-of-memory kill on a parallel worker
Running too many workers multiplies memory use; the OOM killer terminates one, and xdist reports it as crashed.
A test calling os._exit / hard-killing the process
Code under test (or a misbehaving fixture) calls os._exit or sends a fatal signal, terminating the worker without normal teardown.
How to fix it
Isolate the crash by running serially
Re-run without xdist to get a clean traceback and identify the test.
pytest -p no:xdist tests/test_native.py -x
# or reduce parallelism
pytest -n 2Address the root cause
- Segfault → pin/upgrade the native dependency, or run that test in isolation.
- OOM → lower
-n(workers), or raise the runner memory; watch total = per-worker × workers. - os._exit → fix the code/fixture so it raises or returns instead of exiting.
How to prevent it
- Size
-nto the runner’s memory, not just its CPU count. - Keep native dependencies pinned and tested for stability.
- Quarantine known-crashy native tests rather than letting them flake the suite.