The “Disk Not Ejected Properly” notification appears after the fact: a volume that macOS still had mounted is suddenly gone. Pulling a cable is the obvious way to cause it, but it also shows up on its own — after sleep, after a hub loses power, or when a bus-powered drive browns out under load.
The message says nothing about data loss and nothing about the drive being faulty. It only says the unmount step was skipped. The interesting part is the other half of the problem: when you do try to eject properly and macOS refuses. Apple’s own page on that case tells you to “Quit the apps that are using the disk” without telling you which app that is — and macOS actually knows, if you ask it from the command line.
What the message actually reports
Ejecting a volume is two steps. macOS flushes anything still sitting in write buffers to the drive, then it tells the filesystem the volume is no longer in use. The notification fires when step two never happened — the device disappeared while the system still considered the volume live.
Whether anything was lost depends entirely on whether a write was in flight. Copying a large file and pulling the cable can corrupt that file and, on rare occasions, the directory structure. Pulling it while nothing is writing usually costs nothing. Either way the fix is the same: mount it again and let the filesystem check itself, or run diskutil verifyVolume if you want to see the result rather than assume it.
macOS names the process that blocks the eject
This is the part most write-ups miss. When something has the volume open, diskutil does not just fail — it identifies the offender by PID:
$ diskutil eject /Volumes/EjectTest
Unmount of disk20 failed: at least one volume could not be unmounted
Unmount was dissented by PID 16961 (/usr/bin/tail)
Dissenter parent PPID 16959 (/bin/zsh)
“Dissented” is the term macOS uses for a process that vetoes an unmount, and it gives you both the process and its parent. In real use those two lines are usually enough on their own: a PPID of a shell means something you started in Terminal, and a familiar app name means you already know which window to close.
diskutil unmount reports the same thing in a slightly different shape:
$ diskutil unmount /Volumes/EjectTest
Volume EjectTest on disk20s1 failed to unmount: dissented by PID 16961 (/usr/bin/tail)
Dissenter parent PPID 16959 (/bin/zsh)
The BSD umount command is the one to avoid here. It refuses with no idea who is responsible, and even points you back at diskutil:
$ umount /Volumes/EjectTest
umount(/Volumes/EjectTest): Resource busy -- try 'diskutil unmount'
All three ran against the same busy volume on macOS 26.5.2, holding one open file. If you have been carrying a Linux habit of reaching for umount, that is why the Mac version feels less helpful — the diagnostic lives in diskutil.
Finding the file that is still open
When the PID is not enough — a background daemon, or an app you did not realise had touched the disk — lsof gives you the actual open file:
$ lsof /Volumes/EjectTest
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
tail 16961 osxhub 3r REG 1,54 6 18 /Volumes/EjectTest/notes.txt
The USER column here is redacted; everything else is as printed. Two things to know about this command. It only reports processes you own unless you run it with sudo, which matters because Spotlight indexing and backup daemons do not run as you. And a plain lsof /Volumes/Name matches the mount point itself — add +D to walk the whole tree, at the cost of a much slower scan. There is more on reading its output in the lsof guide.
Terminal itself is a common culprit and an easy one to miss: a shell whose working directory is on the volume keeps it busy even with nothing running. cd ~ in every open tab and try again.
Forcing it, and what force costs
$ diskutil unmount force /Volumes/EjectTest
Volume EjectTest on disk20s1 force-unmounted
That succeeds against a volume that just refused a normal unmount. What it does not do is deal with the process that was holding it — the PID from earlier is still running afterwards, still holding a file descriptor, except the filesystem underneath it is gone. Whatever that process had not yet written is not written, and the next read or write it attempts will fail.
So force is the same trade as pulling the cable, minus the surprise. It is the right call for a share whose server is unreachable, and the wrong one while a copy is running. Quitting the app named in the dissent message is nearly always faster than either.
Unmount and eject are not the same thing
These two get used interchangeably and they are not. unmount detaches the volume; the device stays connected and keeps appearing in diskutil list. eject unmounts every volume on the device and then releases the device itself, which is what makes it disappear from the list entirely.
The distinction is what catches people out with multi-partition drives: unmounting the one volume you can see in Finder leaves the drive itself connected, and unplugging at that point still triggers the notification for any partition that was never unmounted. diskutil eject disk4, targeting the whole device rather than a volume, is the one that makes it safe to unplug. Volume and device identifiers are covered in more detail in the diskutil guide.
When the disk drops off on its own
If the notification appears when you have not touched the cable, the drive lost power or the connection dropped, and the usual candidates are worth checking in this order:
- Sleep. Bus-powered drives on some hubs do not survive the Mac sleeping. Apple has published a note for one specific case — internal SATA drives on the Mac Pro (2023) disconnecting after wake, fixed in a macOS update — which is worth knowing mainly as proof that this failure mode is real rather than user error.
- Power budget. An unpowered hub shared with other devices is the most common cause of a drive that drops out only when it gets busy. A powered hub, or the port on the Mac directly, settles this quickly.
- The cable. Marginal cables produce exactly this symptom and nothing else. Swapping the cable before suspecting the drive costs a minute.
The routine that avoids the notification altogether is short: eject the device rather than the volume, run diskutil eject instead of guessing when Finder’s button does nothing, and read the PID it hands you rather than closing apps one by one to find the right one.