brew doctor: Common Warnings and How to Fix Them
A guide to the most common brew doctor warnings — outdated Xcode CLT, unlinked kegs, config issues — and what each one actually means.
brew doctor is Homebrew’s built-in diagnostic tool. It checks your installation for common problems and prints warnings about anything that could cause issues. The problem is that many of its warnings are cryptic, and it’s not always clear which ones matter and which are safe to ignore.
Here’s a guide to the most common brew doctor warnings, what they actually mean, and how to fix them.
How to run it
brew doctor
If everything is fine, you’ll see:
Your system is ready to brew.
More commonly, you’ll see a list of warnings. Let’s walk through the most frequent ones.
Warning: “A newer Command Line Tools (CLT) is available”
Warning: A newer Command Line Tools (CLT) release is available.
Update them from Software Update in System Settings.
What it means: Apple releases Xcode Command Line Tools updates periodically. These contain compilers (clang), linkers, headers, and libraries that Homebrew uses to build packages from source. An outdated CLT version may cause build failures.
How to fix it:
# Option 1: Update via macOS Software Update
softwareupdate --list
softwareupdate --install "Command Line Tools for Xcode-XX.X"
# Option 2: Remove and reinstall CLT
sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install
Does it matter? Yes, if you build any packages from source. If you only install pre-built bottles, it’s less critical but still worth updating for security patches.
Warning: “Unlinked kegs in your Cellar”
Warning: You have unlinked kegs in your Cellar.
Leaving kegs unlinked can lead to build-issues and cause formulae that
depend on those kegs to fail to run properly once built.
[email protected]
node
What it means: Homebrew installs packages to the Cellar (e.g., /opt/homebrew/Cellar/[email protected]/3.12.1/) and then creates symlinks in /opt/homebrew/bin/, /opt/homebrew/lib/, etc. “Unlinked” means the package is installed but its symlinks are missing. The binaries exist but aren’t on your PATH through Homebrew’s standard mechanism.
This usually happens when:
- Two packages provide the same binary and Homebrew unlinked one to avoid conflicts
- A
brew linkcommand failed silently - You ran
brew unlinkat some point and forgot
How to fix it:
# Link a specific package
brew link [email protected]
# If it conflicts with another package, force it
brew link --overwrite [email protected]
# Link all unlinked kegs
brew list --formula | xargs -I{} brew link {} 2>/dev/null
Does it matter? Yes. Unlinked packages won’t be found by other packages during compilation, and their binaries won’t be in your PATH. This is a common cause of “command not found” errors after installing a package.
Warning: “Some installed formulae are missing dependencies”
Warning: Some installed formulae are missing dependencies.
You should `brew install` the missing dependencies:
brew install gettext
What it means: A formula you installed depends on gettext (or another package), but that dependency is not currently installed. This can happen when:
- You manually uninstalled a dependency with
brew uninstall --ignore-dependencies - A formula update added a new dependency that wasn’t pulled in during upgrade
- A dependency was removed by
brew autoremoveincorrectly
How to fix it:
# Install the missing dependency
brew install gettext
# Or reinstall the affected formula to pull in all dependencies
brew reinstall <formula-that-needs-gettext>
Does it matter? Yes. The affected formula may crash at runtime with missing library errors (dyld: Library not loaded), or it may work with degraded functionality.
Warning: “Homebrew’s ‘sbin’ was not found in your PATH”
Warning: Homebrew's "sbin" was not found in your PATH.
If you need to use commands from Homebrew's sbin,
consider adding:
/opt/homebrew/sbin
to your PATH.
What it means: Some formulae install binaries to sbin (system binaries) instead of bin. These are typically daemon-style programs like unbound, dnsmasq, or nginx. Without sbin in your PATH, you can’t run these commands directly.
How to fix it:
# Add to your ~/.zshrc
export PATH="/opt/homebrew/sbin:$PATH"
Does it matter? Only if you use packages that install to sbin. If brew doctor mentions it and you don’t use any sbin binaries, you can safely ignore it.
Warning: “Your Xcode is configured with an invalid path”
Warning: Your Xcode (or CLT) is configured with an invalid path.
Compilers will likely fail. Run:
sudo xcode-select --switch /Library/Developer/CommandLineTools
What it means: The xcode-select path points to a directory that doesn’t exist. This typically happens after an Xcode update or uninstall that didn’t clean up the path.
How to fix it:
# If you have Xcode.app installed:
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
# If you only have CLT:
sudo xcode-select --switch /Library/Developer/CommandLineTools
Does it matter? Yes. Any package that needs to compile from source will fail until this is fixed.
Warning: “Unexpected dylibs/header files”
Warning: Unexpected dylibs were found in /usr/local/lib.
You have unlinked, unexpected dylibs in /usr/local/lib.
/usr/local/lib/libfoo.dylib
What it means: There are library files in /usr/local/lib (or /opt/homebrew/lib) that don’t belong to any installed Homebrew package. These might have been installed by make install from a manual compilation, another package manager, or a leftover from an uninstalled package.
How to fix it: Investigate each file. If it’s from a manual installation you no longer need:
# Check what installed a file
ls -la /usr/local/lib/libfoo.dylib
# Remove it if it's not needed
rm /usr/local/lib/libfoo.dylib
Be careful here — removing a library that something depends on will break that program.
Does it matter? Sometimes. Stray libraries can confuse Homebrew’s linker flags and cause builds to link against the wrong library version. If you’re not building from source, it’s usually harmless.
Warning: “Config scripts exist outside your system or Homebrew directories”
Warning: "config" scripts exist outside your system or Homebrew directories.
/usr/local/bin/python3-config
What it means: There’s a *-config script (used by build systems to find library paths) that Homebrew didn’t install. These scripts can override Homebrew’s packages during compilation, leading to mismatched versions.
How to fix it: This is usually caused by a system-level Python installation or another package manager. The safest fix is to ensure Homebrew’s PATH entries come before /usr/local/bin:
# In ~/.zshrc, Homebrew's shellenv should come first
eval "$(/opt/homebrew/bin/brew shellenv)"
Warning: “Some installed formulae are not readable”
Warning: Some installed formulae are not readable:
/opt/homebrew/Cellar/openssl@3/3.2.0
What it means: File permissions on the Cellar directory are wrong. This can happen if you ran brew with sudo at some point (a common mistake) or if something changed ownership of files in the Homebrew prefix.
How to fix it:
# Fix ownership
sudo chown -R $(whoami) /opt/homebrew
# Fix permissions
chmod -R u+rw /opt/homebrew
When to run brew doctor
Run brew doctor when:
- A
brew installorbrew upgradefails unexpectedly - You see “command not found” for a package you know you installed
- You get linker errors when building software
- Before filing a Homebrew bug report (maintainers will ask for the output)
You don’t need to run it regularly if things are working. The warnings are diagnostic, not preventive.
A note on stout compatibility
Because stout uses the same Cellar directory structure and symlink layout as Homebrew, most brew doctor warnings apply equally to both tools. stout includes its own diagnostic command:
stout doctor
This checks the same things brew doctor does — unlinked kegs, missing dependencies, broken symlinks — but runs in milliseconds instead of the 2-5 seconds brew doctor takes (again, due to Ruby startup overhead). It also checks stout-specific items like index freshness and SQLite database integrity.
If brew doctor reports issues with your Homebrew installation, fixing them before switching to stout ensures a clean transition. stout inherits whatever state your Cellar is in — clean or messy.
Need Rust performance engineering or AI agent expertise?
Neul Labs — the team behind stout — consults on Rust development, performance optimization, CLI tool design, and AI agent infrastructure. We build fast, reliable systems that ship.