Skip to content

Brew cleanup fails with `Device or resource busy .../.nfs...`

Source: Troubleshooting reference

Symptom: an upgrade prints a formula’s beer-mug success line, then fails while cleanup removes an unrelated old keg:

Error: Device or resource busy @ apply2files - .../Cellar/expat/<version>/lib/.nfs...

Root cause: NFS renames an unlinked-but-open file to .nfs* and keeps it until the last process closes it. Any Homebrew executable or shared library can be a holder: this first appeared with the Bash running bootstrap, then with dozens of long-lived dbus-daemon processes mapping an old libexpat.so. Homebrew runs formula cleanup after installs and, every 30 days, a full cleanup. That cleanup exception changes the command’s exit status after the package succeeds, so Bundle misleadingly reports Upgrading <formula> has failed! for each later package too.

Confirm which processes still hold the file:

Terminal window
lsof /path/from/the/error/.nfs...

Fix: wait for the original bootstrap to exit, update the checkout, and retry. On an NFS Homebrew prefix, linux-packages.sh sets the documented HOMEBREW_NO_INSTALL_CLEANUP switch for the run. Installs and upgrades still happen, but cleanup cannot turn their success into failure. The switch does not disable an explicit cleanup; after every process shown by lsof has exited, reclaim the retired keg with:

Terminal window
brew cleanup expat

Old kegs consume some disk until that maintenance succeeds. Do not delete the .nfs* file manually or terminate unrelated holders just to make cleanup pass.