xdg-open: command not found

macOS xdg-open command not found: Real Fix

xdg-open doesn't exist on macOS. Replace it with the native open command or install xdg-utils via Homebrew to keep your scripts portable.

You're running some script you copied from a Linux tutorial, or a Makefile from a cross-platform repo, and the terminal spits back:

zsh: command not found: xdg-open

Nothing is broken. You didn't miss an install step. macOS simply doesn't ship xdg-open, and there's a good reason for that — so before you go hunting for a missing PATH entry, understand what's actually happening.

xdg-open is part of xdg-utils, a freedesktop.org package that gives Linux desktops a standard way to ask "open this file/URL with the user's default app." It reads your $XDG_CURRENT_DESKTOP, checks MIME associations, and dispatches to GNOME's gio open, KDE's kde-open, or whatever's actually registered. macOS has no XDG spec, no freedesktop.org session, and no xdg-utils in the base system. Apple's equivalent is the open command, and it's been part of macOS since forever.

So the fix depends entirely on what you need: swap the command, or install a shim. Let's go through both, plus the edge case where the script hardcodes the binary somewhere weird.

Cause 1: You called xdg-open directly (the most common case)

This is 90% of the hits you'll see. Some shell script, a dev tool, or a tutorial tells you to run xdg-open file.pdf or xdg-open https://example.com. On macOS, the right command is open. It's a native binary at /usr/bin/open and it's already on your PATH.

Try these equivalents:

# Linux
xdg-open report.pdf

# macOS
open report.pdf

# Linux
xdg-open https://apple.com

# macOS
open https://apple.com

# Linux
xdg-open .

# macOS
open .

open hands the path to LaunchServices, which is the same machinery Finder uses when you double-click. That means it respects your default-app settings for any file type. If you've set PDFs to open in Preview but the file was made in Acrobat, open honors your choice. That behavior is identical to xdg-open's intent, just implemented by Apple rather than freedesktop.

One flag worth knowing: open -a "Visual Studio Code" . opens the current folder in a specific app. There's no clean `xdg-open` equivalent, which is one reason Mac folks never reach for it.

If you're editing a script you control, the real fix is to stop calling xdg-open and use a platform check:

if [[ "$(uname)" == "Darwin" ]]; then
  OPEN_CMD=open
else
  OPEN_CMD=xdg-open
fi

"$OPEN_CMD" report.pdf

That's portable, has no dependencies, and won't confuse anyone reading the repo later. Do this if it's your code.

Cause 2: A third-party script hardcodes xdg-open

Now the annoying case. You didn't write the script. Maybe it's a Homebrew formula post-install hook, a Python package calling subprocess.run(["xdg-open", path]), or a Ruby gem that assumes Linux. You can't edit its source cleanly because it'll get overwritten on the next update.

The pragmatic fix is to install xdg-utils from Homebrew, which drops an xdg-open shim into /opt/homebrew/bin (Apple Silicon) or /usr/local/bin (Intel).

brew install xdg-utils

Once that finishes, verify it landed somewhere on your PATH:

which xdg-open
# /opt/homebrew/bin/xdg-open

Here's the catch, and this is where people get confused. The Homebrew xdg-open on macOS isn't a full reimplementation. It's a thin wrapper that ultimately delegates to open for most cases, with a small amount of logic to handle things like browser selection. It works, but it's still going through Apple's LaunchServices under the hood. You're not getting XDG desktop portal behavior — you're getting a translation layer.

That's usually fine. It works for 95% of scripts. But if a script relies on xdg-open returning a specific exit code, or expects $XDG_DATA_DIRS to be populated, it may still misbehave. In that case you're better off patching the script than pretending you're on Linux.

A subtler trap: if you're on Apple Silicon and you installed Homebrew under Rosetta at some point, you might have xdg-utils in /usr/local/bin while your shell PATH prioritizes /opt/homebrew/bin. Then which xdg-open returns nothing even though the file exists. Run brew --prefix to see which prefix your active Homebrew uses and check that directory.

Cause 3: PATH or shell environment is broken

Rare, but worth ruling out before you reinstall anything. If which open also fails, or if basic commands like ls and git are missing, your PATH got clobbered. This shows up most often after editing ~/.zshrc and dropping a colon, or after installing a tool that overwrites PATH instead of appending to it.

Check what you've got:

echo $PATH

A healthy macOS zsh setup looks something like:

/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

If /usr/bin is missing, you've found your problem. Open ~/.zshrc and look for a line like export PATH="/some/tool/bin" — no :$PATH at the end. That wipes everything else. Fix it to export PATH="/some/tool/bin:$PATH" and open a new shell.

There's also the zsh startup chain to consider. Order matters: /etc/zprofile runs path_helper, which is what actually seeds the system paths. If /etc/zprofile got edited or corrupted (rare, but it happens after a botched migration), /usr/bin can vanish from PATH. The fix is to restore it from a stock macOS install or reinstall the OS. But again — check ~/.zshrc and ~/.zprofile first. Nine times out of ten it's user config, not the system.

Quick reference

SituationFix
You wrote the scriptSwap xdg-open for open, or use a uname check for portability
Third-party script hardcodes itbrew install xdg-utils and verify with which xdg-open
which open also failsCheck ~/.zshrc for a broken PATH export; ensure /usr/bin is present
Installed xdg-utils but still not foundApple Silicon vs Intel prefix mismatch — check brew --prefix
Just need to open a file onceopen filename — no install required

Don't waste time searching for a macOS install of xdg-utils from a Linux vendor — it doesn't exist. The open command has been the answer since OS X 10.0, and the Homebrew shim is only there to satisfy scripts that won't take no for an answer.

Related Errors in macOS Errors
null macOS 'The operation can't be completed' error fix NSURLErrorDomain error -1012 Fix 'The operation couldn’t be completed. (NSURLErrorDomain error -1012.)' on macOS Your Mac won't shut down? Force shutdown then fix the hang -600 macOS Error -600: Fix the iTunes/Media Framework Crash in Minutes

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.