You run a Python script, the terminal blinks, and instead of output you get one useless line: zsh: killed. No traceback, no exit code you can see, no hint. Frustrating, I know. Let's fix it.
What 'zsh: killed' actually means
zsh didn't kill your script. zsh is just the messenger. Your shell reports that the process was terminated by a signal — usually SIGKILL (signal 9). Something outside your script sent that signal. On macOS Sonoma, that something is almost always one of three things: the kernel's memory watchdog, the code signing system, or a sandbox restriction.
To confirm which one, run your script and then immediately check the exit code:
python3 your_script.py
echo $?
If you see 137, that's 128 + 9 — SIGKILL. That narrows things down. Now let's find the culprit.
Fix #1: Check for memory pressure (the most common cause)
Sonoma is aggressive about killing processes when memory gets tight, especially Apple Silicon Macs with 8GB or 16GB of RAM. If your Python script loads a big pandas dataframe, a large language model, or does any kind of heavy numerical work, the kernel can kill it before it finishes.
Open a second Terminal window and run this while your script is running:
memory_pressure
You should see a line like System-wide memory free percentage: 15%. If that number drops below 10% while your script runs, you've found your problem. The fix isn't to buy more RAM — it's to reduce the peak memory footprint.
Quick checks:
- Run your script with
/usr/bin/time -l python3 your_script.py. The output includesmaximum resident set sizein bytes. That's your peak memory. Compare it against your available RAM. - If you're using pandas, switch large
read_csvcalls toread_csv(..., chunksize=100000)and process in batches. - If you're loading a model, use
torch.load(..., map_location='cpu')first, then move only what you need to MPS. - Close Chrome. I'm serious. Chrome on Sonoma routinely eats 6–8GB with a normal number of tabs.
After making those changes, run the script again. You should see it complete without the kill message. If it still dies, move to Fix #2.
Fix #2: Re-sign your Python binary (Apple Silicon only)
On M1, M2, and M3 Macs, macOS requires every executable to have a valid code signature. Homebrew's Python, pyenv-installed Pythons, and Python binaries built from source sometimes end up with a broken or missing signature after an OS update. When the kernel tries to load them, it kills the process immediately.
Check the signature on your Python binary:
which python3
codesign -dv --verbose=4 $(which python3)
If you see code object is not signed at all or an error, re-sign it:
codesign --force --deep --sign - $(which python3)
You should see no output — that's success. Now run your script. If it executes, the signature was the issue.
For pyenv users, the fix is often to just reinstall the Python version:
pyenv uninstall 3.12.2
pyenv install 3.12.2
pyenv global 3.12.2
That rebuilds with a fresh signature from Apple's toolchain.
Fix #3: Clear the quarantine flag
If you downloaded your Python script or a .so dependency from the internet, macOS Sonoma attaches a quarantine attribute. When Python tries to load it, Gatekeeper kills the process without a dialog.
Check for quarantine flags:
xattr -l your_script.py
xattr -l /path/to/some_module.so
If you see com.apple.quarantine, strip it:
xattr -d com.apple.quarantine your_script.py
xattr -rd com.apple.quarantine /path/to/your/project
Run your script again. This one catches people off guard because the file runs fine when you test it with cat or open it in an editor — only execution triggers the kill.
Why any of this works
All three fixes address the same underlying issue: macOS Sonoma is stricter about what it lets run. The memory watchdog kills processes that threaten system stability. Code signing prevents tampered binaries from executing. Quarantine stops unreviewed code from running silently. None of these are bugs — they're protections that just happen to hit legitimate Python scripts.
Once you've identified which guardrail is tripping, the fix is usually a one-liner.
Less common variations
Killed on the first line, before any output
If your script dies before the first print() ever runs, it's not a memory problem. It's almost always a code signing issue with a compiled extension. Rebuild your virtualenv:
deactivate
rm -rf venv
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Killed only inside VS Code or PyCharm
Run the exact same script from Terminal. If it works there but dies in your IDE, the IDE is launching a different Python interpreter. Check the interpreter path in your IDE settings — it should match which python3 from Terminal.
Killed when using multiprocessing
Python's multiprocessing uses fork(), which Sonoma handles differently than older macOS. Switch to the spawn method at the top of your script:
import multiprocessing
multiprocessing.set_start_method('spawn', force=True)
This avoids the fork-related kills entirely on Apple Silicon.
Killed with exit code 137 only under Rosetta
Rosetta 2 has its own memory overhead. If you're running an x86 Python build under Rosetta, the kernel counts Rosetta's translation buffers against you. Install a native arm64 Python instead:
arch -arm64 brew install python@3.12
Prevention
- Install Python with Homebrew or pyenv, not with the system Python. Apple's built-in Python 3.9 on Sonoma is unmaintained and gets killed more often.
- Keep your scripts on your internal SSD, not on an external drive or a network mount. External volumes trigger extra security checks that can kill execution.
- Watch memory. Run
memory_pressurebefore launching anything heavy. If you're under 20% free, free up RAM first. - After any macOS point update, re-run
codesign -dv $(which python3). Updates occasionally invalidate signatures on non-Apple binaries. - Never run
sudo python3 script.pyas a workaround. It hides the real problem and can leave root-owned files in your project that cause stranger failures later.
Work through the fixes in order — memory first, signature second, quarantine third. One of them will clear the kill. When it does, note which one in a comment in your script. Future you will thank present you the next time Sonoma decides to tighten the screws.