WiredTiger error (Operation not permitted)

MongoDB WiredTiger error (Operation not permitted) after crash: 3 fixes

MongoDB won't start after a crash because WiredTiger can't create a lock file. Here's how to fix it in 30 seconds, 5 minutes, or 15 minutes depending on what's broken.

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 gets docker 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's mongodb user with a different UID. Same error, same fix — chown -R 999:999 /path/to/volume on 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.

Related Errors in Database Errors
SQLITE_FULL Fix 'database or disk is full' in SQLite with WAL mode 0X80094006 Fix CERTSRV_E_SERVER_SUSPENDED (0x80094006) in 2 Steps 0X40000004 STATUS_RXACT_STATE_CREATED (0X40000004) – What It Means and How to Fix WriteConcernTimeout MongoDB Write Concern Timeout Exceeded – Fix It Fast

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.