macOS 'Operation Not Permitted' Fix: 3 Real Causes

Dealing with 'Operation Not Permitted' on macOS? Here are the three most common triggers and the fixes that actually work, starting with the usual culprit.

You're in Terminal, you run a command that worked last week, and suddenly you get Operation not permitted. Or you're trying to read a file in Finder and the OS just says no. This isn't a corrupted filesystem or a dying drive — it's macOS's privacy layers doing exactly what they're designed to do, but in a way that trips up everyone sooner or later.

What's actually happening here is that macOS (starting with Mojave, so anything from 10.14 onward) gates access to your personal data — Desktop, Documents, Downloads, Photos, Contacts, even your Terminal's ability to touch those folders. When a process hasn't been explicitly granted permission, the OS returns that exact error. Let's fix it.

1. Terminal (or the app) lacks Full Disk Access

This is the most common cause, and the fix is simple but easy to miss because the setting is buried in System Settings. If you're using zsh, bash, or any terminal-based tool (like git or vim) and it can't read or write files in protected directories, the terminal app itself is being blocked.

The reason step 1 works is that Full Disk Access isn't a per-command permission — it's an app-level grant. Once your terminal app has it, every command you run inherits that access. Without it, you'll see Operation not permitted even though you're the admin and the file is owned by you.

Fix it like this:

  1. Open System Settings (or System Preferences on older macOS) → Privacy & SecurityFull Disk Access.
  2. Click the lock icon and enter your password if needed.
  3. Click the + button, then navigate to /System/Applications/Utilities/Terminal.app (or your preferred terminal like iTerm).
  4. Add it, then quit Terminal completely (Cmd+Q) and reopen it.

One critical gotcha: the toggle may already appear on but still not work. That's because macOS sometimes tracks a stale authorization. Toggle it off, restart Terminal, then toggle it back on and restart again. That forces a fresh TCC evaluation.

If you're using a third-party terminal like iTerm2, add that instead — adding Terminal won't help. Also, any app that shells out to command-line tools (e.g., a code editor running build scripts) needs its own Full Disk Access.

2. The process is running from launchd or cron — and that's the problem

Here's a scenario that drives people nuts: you write a shell script and run it manually — it works fine. Then you schedule it with cron or launchd, and suddenly it fails with Operation not permitted. The script hasn't changed. The permission for Terminal hasn't changed. What changed is the parent process.

What's actually happening here is that macOS's TCC (Transparency, Consent, and Control) framework evaluates permissions based on the responsible process. When cron or launchd runs your script, the responsible process is cron or launchd, not Terminal. And neither of those has Full Disk Access — and you can't grant it to them in System Settings because they're not user apps.

The fix most people land on is giving cron or the launchd job Full Disk Access via a lower-level trick, but honest answer: that doesn't stick reliably across reboots. The better approach is to run your scheduled jobs through a user-level agent that can get permission.

Here's the fix that actually holds:

  1. Create a launchd plist in ~/Library/LaunchAgents/ that runs your script as your user (not root).
  2. After loading it, add your terminal app (the one you use to manage it) to Full Disk Access as in fix #1.
  3. Also add /usr/sbin/cron if you must stick with cron — on macOS 13 Ventura and later, you can add it via Full Disk Access if you navigate to the exact path. It's ugly but works.

A quick test: instead of scheduling, run launchctl submit -l test -- /path/to/script with your script referencing a protected file. If it errors, you know it's the parent process. If it succeeds, your launchd config is the culprit.

3. You're on macOS 15 Sequoia and the path is just different

Sequoia (15.0) introduced a subtle change that caught a lot of developers off guard. Previously, if you'd granted Full Disk Access to Terminal, it applied system-wide. In Sequoia, the system started differentiating between the Terminal process and the zsh subprocess it spawns. In some builds, you need to grant access to zsh (or the specific shell binary) in addition to Terminal.

The reason this one is easy to miss is that the error appears intermittently — some commands work, others don't. It depends on whether the syscall is made by the shell itself or by a child process that doesn't inherit the sandbox extension correctly.

What fixes this:

  1. Re-open System Settings → Full Disk Access.
  2. Click the + and add /bin/zsh (or /bin/bash if you switched). You'll need to press Cmd+Shift+G in the file picker to enter the path directly.
  3. Grant it, then restart the terminal.

If you run scripts with other interpreters (Python, Ruby), add those binaries too. The general rule: anything that inherits your terminal's permissions but isn't the terminal app itself may need an explicit entry.

I've also seen cases where the issue persists because the user has duplicated Terminal.app via a symlink or a third-party wrapper. macOS treats each unique binary as a separate entity. If you launch from a symlink, add the real path — symlink grants don't always propagate.

Quick-reference table

TriggerError patternFix
Terminal app lacks Full Disk AccessAny command touching Desktop/Documents failsAdd Terminal to Full Disk Access, toggle off/on
cron/launchd parent process blockedScheduled job fails, manual run worksUse LaunchAgent, or add cron binary to Full Disk Access
Sequoia shell subprocess not authorizedIntermittent failures in zshAdd /bin/zsh (and other interpreters) to Full Disk Access

One last thing: don't waste time resetting the TCC database (sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db ...) unless it's a last resort. I've had mixed results and it can revoke permissions for other apps, creating a bigger mess. Stick with the app-level grants — they're the intended mechanism and they work when you match the right process.

Related Errors in macOS Errors
Install Failed – An error occurred while installing the selected updates. macOS 'Install Failed' Error on Big Sur or Monterey PKDownloadError error 8 macOS 'PKDownloadError error 8' fix: stalled installer null macOS 'The operation can’t be completed because the original item for ‘filename’ can’t be found' fix -10810 or -10811 or generic launch failure macOS 'The application cannot be opened' error fix

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.