Mac users frequently encounter frustrating system alerts when attempting to move, rename, unmount, or empty a file into the Bin: “The operation can’t be completed because the item is in use.” Finder often fails to specify which active application or background daemon has an open lock on the file. Even after quitting visible GUI applications, background agents, cloud synchronization utilities, or indexing daemons may continue holding an active filesystem handle, preventing any modification or safe volume ejection.
Rather than rebooting your Mac to release stubborn file locks, macOS provides a robust, built-in UNIX utility via Terminal: lsof (List Open Files). By combining lsof with precise target paths, you can instantly identify the exact process name, process identifier (PID), and active user holding the lock, allowing you to terminate the blocking task cleanly and safely release the item.
Understanding How macOS Locks Open Files
In UNIX-based operating systems like macOS, every open document, network socket, dynamic library, and directory connection is represented as a file descriptor. When an application opens a document—even in a read-only state—the macOS kernel assigns an active file handle to the responsible process.
Finder prioritises filesystem integrity by preventing operations that could lead to data corruption or kernel panic. However, background processes such as Quick Look thumbnailers, Spotlight’s mds_stores indexer, or cloud daemons (such as Dropbox or OneDrive) frequently retain locks long after you finish interacting with a file. Using lsof bridges this visibility gap by querying the kernel’s active open file tables directly.
Using lsof to Identify the Locking Process
To inspect active file handles, launch Terminal from Applications > Utilities or summon it via Spotlight (Command + Space, type Terminal, and press Enter).
Querying a Specific File
The most straightforward method to identify who is locking an individual file is to execute lsof followed by the absolute file path:
lsof "/path/to/problematic/file.pdf"
Tip: Instead of manually typing long file paths, type lsof (with a trailing space) and drag-and-drop the problematic file directly from Finder into the Terminal window. macOS automatically populates the escaped absolute path.
Executing with Elevated Privileges (sudo)
If the file is locked by a root-level daemon, a secondary user account, or a system background service, standard user queries may return blank output due to macOS security sandboxing. To query all system-level descriptors across all user domains, prefix the command with sudo:
sudo lsof "/path/to/problematic/file.pdf"
Enter your macOS administrator password when prompted (characters will not appear on screen) and press Enter.
Interpreting the Terminal Output
When an active lock exists, lsof prints structured column data resembling the following:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
Preview 48212 alexander txt REG 1,4 14829104 892144 /Users/alexander/Documents/report.pdf
Focus on these key columns:
- COMMAND: The executable binary holding the file lock (for example,
Preview,QuickLookUIService, ornode). - PID: The unique Process Identifier assigned to the running application (e.g.,
48212). You will need this numeric ID to terminate the process if it refuses to quit gracefully. - USER: The macOS account name executing the process.
- FD: The file descriptor status (e.g.,
cwdfor current working directory,txtfor program text/code, orwfor write access).
Finding Processes Locking an Entire Directory or External Volume
When attempting to eject an external USB drive, SD card, or network volume, macOS often alerts: “The disk wasn’t ejected because one or more programs may be using it.” To discover every open file handle across an entire mounted volume or directory tree, use the +D flag (recursive search):
sudo lsof +D "/Volumes/ExternalDrive"
The +D parameter instructs lsof to traverse the entire directory tree beneath the specified path, printing every active lock across all subdirectories on that volume.
Releasing the File Lock Safely
Once you identify the offending process, you have two approaches to release the filesystem lock:
Approach 1: Graceful Termination via GUI or Activity Monitor
If the COMMAND column indicates a standard GUI application (such as Pages, Photoshop, or Preview), switch to that application and save your progress, close the document window, or quit the application (Command + Q). Once closed, re-check lsof to confirm the file handle has freed.
Approach 2: Terminating the Process via Command Line
If the process is a hanging background daemon or unresponsive service, you can terminate it directly using its PID:
- First, attempt a graceful termination signal (
SIGTERM):kill 48212 - If the process remains active after five seconds, issue an unconditional forced kill (
SIGKILL):kill -9 48212 - If the task is owned by
rootor_spotlight, prependsudo:sudo kill -9 48212
As soon as the process terminates, the kernel closes the file descriptor, allowing you to delete, move, or eject the volume immediately without error.
Handling Common Persistent Daemons
Two specific system processes account for a high percentage of mysterious lock errors on macOS:
- QuickLookUIService: macOS’s Finder preview engine often hangs on corrupt video or PDF assets. Terminating this service via
killall QuickLookUIServicesafely releases file locks; macOS automatically restarts the service on demand. - mds and mds_stores: Spotlight indexes new volumes upon connection. If indexing locks a disk from ejecting, you can temporarily disable indexing on that specific volume using
sudo mdutil -i off /Volumes/ExternalDrivebefore running your unmount command.
Leveraging lsof provides precise insight into macOS process management, eliminating guesswork and safely resolving stubborn file locking conflicts.