Your MongoDB instance crashed, the server rebooted, and now mongod won't come back up. The log fills with something like WiredTiger error (13) [timestamp] wiredtiger_open: __wt_open: open: /var/lib/mongodb/WiredTiger.turtle: Permission denied or the more generic [timestamp] WiredTiger error (1) [timestamp] wiredtiger_open: __wt_open: open: /var/lib/mongodb/WiredTiger: Operation not permitted. You check disk space, it's fine. You check the config, unchanged. You restart mongod again and get the same wall of red.
Take a breath. This error is almost never the database itself being corrupt. WiredTiger, MongoDB's storage engine, opens a handful of files when it starts — the turtle file, the lock file, the journal — and if it can't get permission to create or truncate any one of those, it bails before it ever touches your data. That's good news. It means the fix is usually about ownership or a stale lock, not recovery.
Work through these three fixes in order. Stop as soon as mongod comes back and you can connect with mongosh.
Fix 1: Fix data directory ownership (30 seconds)
This is the fix for 9 out of 10 cases. When MongoDB crashed uncleanly, it may have been running as a different user than the one you're starting it as now. Or — and this is the classic one — you ran mongod once manually with sudo and now all the WiredTiger files are owned by root. The mongodb system user can't open them anymore, and you get Operation not permitted.
Check ownership first:
ls -la /var/lib/mongodb/ | head -20
You should see mongodb mongodb as the owner on every file. If you see root root or your own username on any of the WiredTiger*, .turtle, journal, or collection-*.wt files, that's your problem.
Fix it with a recursive chown:
sudo chown -R mongodb:mongodb /var/lib/mongodb
sudo chmod -R 755 /var/lib/mongodb
After running that, restart the service:
sudo systemctl restart mongod
sudo systemctl status mongod
You should see active (running) and a line in the status output that says Waiting for connections. Try connecting:
mongosh --eval "db.runCommand({ping: 1})"
If that returns { ok: 1 }, you're done. Don't read further. If you're on macOS with Homebrew and the path is /opt/homebrew/var/mongodb or /usr/local/var/mongodb, swap the path — same fix applies. Your user needs to own those files, not root.
Fix 2: Clear stale lock files and restart cleanly (5 minutes)
If permissions are already correct and MongoDB still won't start, the next suspect is a leftover lock from the crash. WiredTiger writes a mongod.lock file at startup and clears it on graceful shutdown. After a hard crash, that file stays behind — and depending on how the crash went, the file might be empty, might have a PID in it, or might be genuinely locked by a process the kernel hasn't fully reaped.
First, make absolutely sure no mongod process is running:
ps aux | grep mongod
If you see more than the grep line itself, kill it properly:
sudo pkill -9 mongod
sleep 2
ps aux | grep mongod
Now check the lock file:
ls -la /var/lib/mongodb/mongod.lock
cat /var/lib/mongodb/mongod.lock
An empty file or stale PID means it's safe to remove. Do not skip this — that's the whole point of this step:
sudo rm /var/lib/mongodb/mongod.lock
Then restart and watch the log live so you see exactly what happens:
sudo systemctl start mongod
sudo tail -f /var/log/mongodb/mongod.log
You're looking for the line Waiting for connections. If WiredTiger gets past wiredtiger_open and starts replaying the journal, you'll see entries like Recovering log 1 through 2 — that means it's doing its job. Let it finish. A large journal replay can take 30 seconds to a few minutes on a busy instance. Don't kill it.
Real scenario I've seen a dozen times: a Docker container running MongoDB getsdocker kill'd or the host OOM-kills it, the container restarts with a fresh filesystem UID mapping, and now the WiredTiger files inside the mounted volume are owned by UID 999 (mongodb inside the container) but the volume is owned by the host'smongodbuser with a different UID. Same error, same fix —chown -R 999:999 /path/to/volumeon the host.
Fix 3: Run WiredTiger salvage on the damaged files (15+ minutes)
If ownership is right, the lock is gone, and WiredTiger still throws Operation not permitted — or worse, it starts throwing WT_CORRUPT or WT_READ_CHECK errors as it opens files — you're dealing with actual damage from the crash, not a permissions problem. Time to get out the heavy tool.
Before anything else, back up the data directory. If salvage makes things worse, you'll want the original:
sudo systemctl stop mongod
sudo cp -a /var/lib/mongodb /var/lib/mongodb.backup.$(date +%Y%m%d)
Now start mongod with the salvage flag. This tells WiredTiger to rebuild whatever tables it can from the raw file data, dropping rows it can't read:
sudo -u mongodb mongod --dbpath /var/lib/mongodb --wiredTigerSalvage true --logpath /tmp/mongo-salvage.log --fork
Watch /tmp/mongo-salvage.log. You'll see a stream of salvage messages, one per collection file. Depending on how much data you have, this takes anywhere from a couple of minutes to an hour. It's disk-bound and single-threaded, so don't expect it to be fast.
When it finishes, connect with mongosh, list your databases, and spot-check the collections you care about:
show dbs
use yourapp
db.yourcollection.countDocuments()
If counts look sane, export a logical dump with mongodump immediately. You want that clean copy on disk before you trust the salvaged files for anything:
mongodump --out /tmp/dump-$(date +%Y%m%d) --gzip
Now shut down cleanly, delete the salvaged data directory, and restore from the dump into a fresh one:
sudo systemctl stop mongod
sudo mv /var/lib/mongodb /var/lib/mongodb.salvaged
sudo mkdir -p /var/lib/mongodb
sudo chown mongodb:mongodb /var/lib/mongodb
mongorestore --gzip /tmp/dump-$(date +%Y%m%d)
sudo systemctl start mongod
You should see Waiting for connections and a clean startup log with no salvage or recovery messages. That's the end of it.
What I'd actually check first
One more thing worth knowing: the vast majority of Operation not permitted errors after an unclean shutdown are permissions, full stop. Before you go chasing salvage or corruption, run ls -la on the data directory and look at the owner. If it says root, you already know the fix. Save yourself the 15 minutes.
And a note for next time — set up proper shutdown handling. If you're on Kubernetes, use terminationGracePeriodSeconds: 60 and a preStop hook that runs mongod --shutdown. If you're on systemd, systemctl stop mongod and not kill -9. Unclean shutdowns happen, but they don't have to be your weekend project.