If you run Ansible on macOS and see a crash about +[__NSCFConstantString initialize] and fork(), this is a known conflict between Python's multiprocessing, Ansible's forking behavior, and macOS's Objective-C runtime safety checks. Here's exactly what causes it and how to fix it.
The Error
objc[22868]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
objc[22868]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
Root Cause
Starting with macOS High Sierra (10.13), Apple added a safety check in the Objective-C runtime that crashes any process that calls fork() without immediately calling exec() if Objective-C classes are being initialized in another thread.
Ansible uses Python's multiprocessing module to fork child processes for parallel task execution. When Python forks on macOS, the child process inherits the parent's memory — including partially-initialized Objective-C classes. macOS detects this as unsafe and kills the process.
This affects:
- Ansible with
forks > 1(the default is 5) - Any Python script that uses
multiprocessingoros.fork()on macOS - All macOS versions from High Sierra onward (including Ventura, Sonoma, Sequoia)
Fix 1: Environment Variable (Recommended)
Current Terminal Session Only
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
ansible-playbook site.yml
Permanent Fix (All Sessions)
Add to your shell profile:
# For bash
echo 'export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES' >> ~/.bash_profile
# For zsh (default on modern macOS)
echo 'export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES' >> ~/.zshrc
# For fish
set -Ux OBJC_DISABLE_INITIALIZE_FORK_SAFETY YES
Verify It's Set
env | grep OBJC
# Should show: OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
Fix 2: Reduce Forks to 1
If you prefer not to disable the safety check:
# ansible.cfg
[defaults]
forks = 1
Or per-command:
ansible-playbook site.yml -f 1
This eliminates forking entirely but runs tasks sequentially (slower for multi-host playbooks).
Fix 3: Use a Python Virtual Environment
Sometimes the issue is triggered by system Python interacting with macOS frameworks:
# Create a clean venv
python3 -m venv ~/ansible-venv
source ~/ansible-venv/bin/activate
pip install ansible
# Run Ansible from the venv
ansible-playbook site.yml
Virtual environments can reduce (but not always eliminate) the fork conflict.
Fix 4: Run Ansible in a Container
Avoid macOS fork issues entirely by running Ansible in Docker:
docker run --rm -it \
-v $(pwd):/ansible \
-v ~/.ssh:/root/.ssh:ro \
-w /ansible \
python:3.12-slim \
bash -c "pip install ansible && ansible-playbook site.yml"
Or use the official Ansible execution environment:
pip install ansible-navigator
ansible-navigator run site.yml --mode stdout
Which Fix Should You Use?
| Fix | Pros | Cons |
|---|---|---|
OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES | Simple, one line, keeps parallel execution | Disables a macOS safety check |
forks = 1 | No env changes needed | Very slow for multi-host playbooks |
| Virtual environment | Cleaner Python setup | Doesn't always fix the issue |
| Docker/container | Complete isolation | More complex setup |
For most users, Fix 1 (environment variable) is the right answer. The safety check protects against a theoretical crash in Objective-C class initialization after fork — which doesn't affect Ansible's actual behavior. Disabling it is safe for Ansible usage.
Affected macOS Versions
| macOS Version | Affected? |
|---|---|
| High Sierra (10.13) | ✅ First version with this check |
| Mojave (10.14) | ✅ |
| Catalina (10.15) | ✅ |
| Big Sur (11) | ✅ |
| Monterey (12) | ✅ |
| Ventura (13) | ✅ |
| Sonoma (14) | ✅ |
| Sequoia (15) | ✅ |
Links
Related Articles
- How to Install Ansible Step-by-Step
- How to Fix Ansible Connection Failures
- Ansible Indentation Errors
- Ansible Privilege Escalation Errors
- Ansible Best Practices
- Ansible Tutorial for Beginners
Conclusion
The macOS fork error is a well-known Ansible issue with a simple fix: export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES in your shell profile. This is safe for Ansible usage and preserves parallel task execution. Add it once to ~/.zshrc and forget about it.