macOS: xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)
Hi, it's BlueByte. The morning after a macOS upgrade you type git status and get xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun. Then make, clang, brew install and npm install fail the same way. Your repositories are fine and nothing needs reinstalling except one Apple package. We'll walk through what the shims are actually looking for, why an upgrade empties that directory, how to confirm which case you have, the fix per case, and how to make the next upgrade painless.
What xcrun is complaining about, and the shapes it takes
On macOS the developer commands in /usr/bin — git, clang, make, swift, python3 — are wrappers. Apple's Command Line Tools documentation calls them shims: each one asks for the active developer directory and runs the real tool from inside it. That directory is either /Library/Developer/CommandLineTools, where the standalone Command Line Tools package installs, or /Applications/Xcode.app/Contents/Developer when Xcode is selected. The error is xcrun saying the directory it was told to use has no xcrun inside:
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrunThe sibling appears when the selected path is Xcode and Xcode is gone:
xcrun: error: active developer path ("/Applications/Xcode.app/Contents/Developer") does not exist
Use `sudo xcode-select --switch path/to/Xcode.app` to specify the Xcode that you wish to use for command line developer tools, or use `xcode-select --install` to install the standalone command line developer tools.Both mean the same thing: the pointer is set, the target is empty or missing.
Why a macOS upgrade empties the directory, and the other causes
A major macOS upgrade. This is the common one. Apple's own guidance is to check for a new Command Line Tools release after a macOS upgrade, because the installed package may be incompatible with the new macOS. In practice the upgrade leaves /Library/Developer/CommandLineTools present but without its usr/bin, so xcode-select -p still prints the path and every shim fails.
Xcode was deleted or moved. If xcode-select was pointed at /Applications/Xcode.app and you dragged Xcode to the Trash, renamed it to Xcode-15.app, or removed it to free disk space, the pointer dangles. You get the second message above.
The pointer was changed by hand. sudo xcode-select -s to a path that is not a developer directory, or a DEVELOPER_DIR environment variable exported in a dotfile or a CI job, overrides the system setting for that shell.
The install never finished. The Command Line Tools dialog was cancelled, or a download failed, leaving a partial directory. The package receipt tells you.
Check the path before you install anything
Three commands sort the causes, and none of them change anything:
xcode-select -p
ls /Library/Developer/CommandLineTools/usr/bin/xcrun
pkgutil --pkg-info=com.apple.pkg.CLTools_Executables
echo "DEVELOPER_DIR=${DEVELOPER_DIR:-unset}"/Library/Developer/CommandLineTools
ls: /Library/Developer/CommandLineTools/usr/bin/xcrun: No such file or directory
No receipt for 'com.apple.pkg.CLTools_Executables' found at '/'.
DEVELOPER_DIR=unsetPointer set, binary missing, no receipt — the package is gone and cause one applies. A receipt with a version: line but no binary is a broken directory, which needs the same fix. A pointer at Xcode.app that ls /Applications cannot find is cause two. A DEVELOPER_DIR that is not unset is cause three, and it wins over xcode-select for that shell.
Fix 1: install the Command Line Tools again
Ask macOS to fetch the package. Apple documents the command and the note it prints; a system dialog follows, and you click Install and accept the licence:
xcode-select --installxcode-select: note: install requested for command line developer toolsThe download is large — the package carries the full macOS SDK — and needs an administrator account. Nothing is broken if the command instead answers that the tools are already installed and points you at Software Update — the wording varies by macOS version — while the binary is still missing. That is the broken-directory case: remove the directory Apple's uninstall steps name, then request the install again:
sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --installNothing of yours lives in that directory; it holds only Apple's toolchain and SDK, and the package recreates it. Software Update in System Settings, or softwareupdate --list, may also offer a Command Line Tools release for the current macOS; installing it from there is the same package.
Fix 2: point xcode-select at the Xcode you actually have
If Xcode is installed, you do not need the standalone package at all — Apple's docs are clear that Xcode bundles the same tools. Select it, or reset to the default search:
sudo xcode-select -s /Applications/Xcode.app
xcode-select -p/Applications/Xcode.app/Contents/Developersudo xcode-select --reset clears a hand-set path and lets the shims find whichever developer directory exists. Both commands change the setting for every user on the Mac, which is why they need sudo.
Fix 3: an environment variable is overriding the system path
DEVELOPER_DIR takes precedence over xcode-select for the shell that has it set. Find where it comes from and remove it, or point it at a real directory:
grep -n DEVELOPER_DIR ~/.zprofile ~/.zshrc ~/.bash_profile 2>/dev/null
unset DEVELOPER_DIR
xcrun --find clangThis is also the right tool for CI: export DEVELOPER_DIR=/Applications/Xcode-16.app in the job instead of running xcode-select -s on a shared runner.
A real case: git dead after an overnight upgrade
A developer let a major macOS upgrade run overnight. In the morning git pull failed with the invalid active developer path message, and so did brew upgrade, which needs git. xcode-select -p still printed /Library/Developer/CommandLineTools; pkgutil --pkg-info reported no receipt. They ran xcode-select --install, clicked Install in the dialog, waited for the download, and git --version answered again with the Apple Git build for the new package. brew doctor was clean without any Homebrew change, because Homebrew had only been waiting on git.
Check it end to end and keep it from coming back
Verify with the shim, then with a tool that goes through it:
xcode-select -p
xcrun --find clang
git --version
pkgutil --pkg-info=com.apple.pkg.CLTools_Executables/Library/Developer/CommandLineTools
/Library/Developer/CommandLineTools/usr/bin/clang
git version 2.x.y (Apple Git-nnn)
package-id: com.apple.pkg.CLTools_Executables
version: 26.x.0.0.1.…The exact versions depend on the package Apple ships for your macOS. To stay ahead of the next upgrade: run xcode-select -p and git --version right after any major macOS update, before the first meeting; keep Software Update on so new Command Line Tools releases appear as updates; and if you rely on Xcode, select it explicitly so a stale standalone package cannot be the active path.
How this differs from "tool 'xcodebuild' requires Xcode" and the licence prompt
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance is not a missing-tools problem: the Command Line Tools are installed and working, but xcodebuild and xctrace ship only with Xcode. Install Xcode and select it with Fix 2. And You have not agreed to the Xcode license agreements means everything is installed and the shims found it; run sudo xcodebuild -license once.
Next time you hit this, walk these checks back in order: xcode-select -p, ls the usr/bin/xcrun under that path, pkgutil for the receipt — and let xcode-select --install do the rest.
Related questions
Will reinstalling the Command Line Tools delete anything of mine?
No. /Library/Developer/CommandLineTools holds only Apple's toolchain, SDK and man pages; removing and reinstalling it does not touch your repositories, Homebrew, or projects. Homebrew formulae built against the old SDK keep working, and brew doctor will tell you if anything needs a rebuild.
xcode-select --install says the tools are already installed, but git still fails.
The directory exists but is empty or partial, so the installer declines. Remove it with sudo rm -rf /Library/Developer/CommandLineTools and run xcode-select --install again, or install the current Command Line Tools release through Software Update.
I have Xcode. Do I still need the standalone Command Line Tools?
No. Xcode bundles the same tools; run sudo xcode-select -s /Applications/Xcode.app so the shims use it. The standalone package is for machines without Xcode. You can only install one version of the package at a time, but Xcode and the package can coexist.
Why does this happen after every major macOS upgrade?
The Command Line Tools package is tied to a macOS release, and Apple's documentation says to check for a new release after upgrading because the installed one may be incompatible. Treat xcode-select -p plus git --version as part of your post-upgrade checklist.
Can I fix this for one terminal session without sudo?
If a valid developer directory exists somewhere, yes: export DEVELOPER_DIR=/Applications/Xcode.app for that shell and the shims use it. If no toolchain is installed at all, nothing to point at exists, and you need xcode-select --install.
References
- Apple Developer Documentation — Installing the command-line tools (xcode-select --install, /Library/Developer/CommandLineTools, pkgutil receipt, update after macOS upgrade, uninstall)
- Apple Technical Note TN2339 — Building from the Command Line with Xcode FAQ (shims in /usr/bin, xcode-select --print-path / -switch)
Haneul Seo
Infrastructure engineer · 10+ years running Linux fleets
More in this category
systemd: Start request repeated too quickly
systemd refuses to start a unit that was started more than StartLimitBurst times (default 5) within StartLimitIntervalSec (default 10s), and Restart= counts against that limit. With the 100 ms default RestartSec a crashing service burns all five attempts in under a second. Find the real crash in the journal, fix it, run reset-failed, and give restarts room with RestartSec.
SSH: Received disconnect ... Too many authentication failures
Your agent is offering more keys than the server will let you try. Every public key sshd looks at burns one of the MaxAuthTries attempts — six by default, often three on a hardened host — so the right key never gets its turn and the server hangs up before you type anything. IdentitiesOnly=yes with an explicit IdentityFile pins the connection to one key and the attempt count drops to one.
Active Directory: replication fails with error 1722, The RPC server is unavailable
RPC reports 1722 (0x6ba, RPC_S_SERVER_UNAVAILABLE) when a lower layer fails to connect, so the real fault is almost never RPC itself — it is DNS, a blocked port, or a host-side setting on one of the two domain controllers. repadmin tells you which partner is failing, dcdiag /test:dns rules out name resolution, and Test-NetConnection plus the dynamic port range settle the firewall question. The most common miss is a rule that allows TCP 135 but not 49152–65535.
Windows Server RDS: The remote session was disconnected because there are no Remote Desktop License Servers available to provide a license
The 120-day RD Licensing grace period ended and the session host has no usable license server, so it refuses sessions. GetGracePeriodDays returning DaysLeft 0 and an empty SpecifiedLSList confirm it in seconds. The fix is a real, activated license server with CALs that are new enough for the host — a 2019 CAL cannot serve a 2022 session host — configured through the deployment or the Licensing policies, plus RPC ports open between the two.
Windows 11: "Your organization's security policies block unauthenticated guest access" when opening a NAS share (0x80070035)
The SMB client on Windows 10 Enterprise/Education/Pro for Workstations, Windows 11 Pro and Windows Server 2019+ refuses guest logons by default, and Windows 11 24H2 Enterprise/Pro/Education also requires SMB signing, which guest sessions can't do. A NAS share that only offers guest access therefore fails with the 'block unauthenticated guest access' dialog, Error code 0x80070035, or System error 3227320323, and Event ID 31017 'Rejected an insecure guest logon' lands in the SmbClient/Security log. The fix Microsoft recommends is a real account on the NAS and signing support in its firmware; Set-SmbClientConfiguration -EnableInsecureGuestLogons $true (plus -RequireSecuritySignature $false on 24H2) is the escape hatch, and it costs you signing and encryption on that client.
Ubuntu/Debian: E: Could not get lock /var/lib/dpkg/lock-frontend — who holds it and how to wait for it
Another package manager, usually Ubuntu's unattended-upgrades fired by a persistent systemd timer at boot, holds the dpkg frontend lock while your apt-get runs. apt-get gives up at once while apt waits because Ubuntu ships binary::apt::DPkg::Lock::Timeout "120" for the apt binary only. Read the PID from the message, let the run finish or pass -o DPkg::Lock::Timeout=<seconds> to apt-get, run dpkg --configure -a only after a genuinely interrupted run, and never delete the lock file: it is an fcntl lock the kernel releases when the holder exits.