cheat sheet
mdfind
Query macOS's Spotlight index from the shell — fast name, content, and metadata search across the whole filesystem, with scope, attributes, and live-update modes.
mdfind — Spotlight Search From the Terminal
What it is
mdfind is the command-line interface to macOS's Spotlight metadata index, shipped by Apple as part of the base system since Mac OS X 10.4 (Tiger). It queries the same index the magnifying-glass menu in the upper-right corner uses, returning matching file paths on stdout in milliseconds — even across a multi-terabyte volume — because the work was done at index time, not at query time. macOS Tahoe (macOS 26) redesigned the menubar Spotlight UI with Applications/Files/Actions/Clipboard buttons, third-party API support, and Apple-Intelligence-assisted ranking — mdfind's CLI surface, query syntax, and flags are unchanged by that overhaul; the same commands still work as they have for two decades. Reach for mdfind whenever you want fast filename, content, or metadata search on an indexed volume; fall back to find or fd for unindexed locations (network mounts, hidden system paths, volumes you have explicitly opted out of indexing) or when you need expression filters Spotlight does not understand.
Install
mdfind ships with macOS and cannot be installed separately — it lives in /usr/bin/mdfind, signed by Apple, and is always available on a default install. The companion tools mdls, mdimport, and mdutil ship in the same directory.
which mdfind
# /usr/bin/mdfind
mdfind --help 2>&1 | head -3
# Companion tools
which mdls mdimport mdutil
Output:
/usr/bin/mdfind
/usr/bin/mdls
/usr/bin/mdimport
/usr/bin/mdutil
Syntax
mdfind accepts a query string and prints one matching absolute path per line. The query language is Apple's NSMetadataQuery syntax — broadly similar to NSPredicate — with shortcuts for plain text searches.
mdfind [OPTIONS] QUERY
Output: (none — exits 0 on success)
The simplest query is a bare word: mdfind alice returns every indexed file whose name, content, or metadata contains "alice". Structured queries use attribute names and comparison operators inside the query string.
mdfind alice # free text — name, content, tags
mdfind "kMDItemFSName == 'report.pdf'" # exact filename
mdfind "kMDItemContentType == 'public.image'" # all images, by UTI
mdfind "kMDItemPixelHeight > 2000" # tall images
Output:
/Users/alice/Documents/report.pdf
/Users/alice/Downloads/report.pdf.bak
Essential options
| Option | Meaning |
|---|---|
-onlyin DIR | Restrict the search to paths under DIR |
-name NAME | Shortcut for kMDItemFSName == "*NAME*"c (case-insensitive contains) |
-count | Print only the number of matches, not the paths |
-0 | Separate results with NUL bytes (safe for xargs -0) |
-live | Keep the query open and stream additions/removals as the index changes |
-reprint | With -live, reprint the full result set on every update instead of streaming diffs |
-literal | Treat the query as a literal string (no shortcuts, no globs) |
-interpret | Parse the query the way the Spotlight menu does (fuzzy, multi-word) |
-s NAME | Use a named saved Smart Folder query |
-attr ATTR | Print the value of ATTR alongside each result |
mdfind -onlyin ~/Documents -name "*.pdf"
mdfind -count "kMDItemContentType == 'public.image'"
mdfind -0 -name ".DS_Store" | xargs -0 rm -v
Output:
/Users/alice/Documents/q1-report.pdf
/Users/alice/Documents/contracts/lease.pdf
4128
Query language essentials
The structured query language is what makes mdfind more powerful than find. A query is one or more predicates of the form ATTR OP VALUE, joined with && and ||. Every attribute Spotlight indexes is queryable; mdls FILE (covered below) lists the attributes a particular file carries.
The comparison operators are:
| Operator | Meaning |
|---|---|
== | Equal |
!= | Not equal |
<, <=, >, >= | Numeric / date comparison |
*= | Substring match (use with c modifier for case-insensitive: *=[c]) |
&&, || | AND / OR |
(...) | Grouping |
Modifiers in square brackets after the operator change matching behaviour:
| Modifier | Effect |
|---|---|
[c] | Case-insensitive |
[d] | Diacritic-insensitive (é matches e) |
[cd] | Both |
# Substring, case-insensitive
mdfind "kMDItemDisplayName == '*invoice*'cd"
# Compound query
mdfind "kMDItemContentType == 'public.image' && kMDItemPixelWidth > 4000"
# Numeric date — files modified in the last day (seconds since 2001-01-01)
mdfind "kMDItemFSContentChangeDate > \$time.today(-1)"
# Tag-based search (Finder colour tags)
mdfind "kMDItemUserTags == 'Project Phoenix'"
Output:
/Users/alice/Documents/invoice-2026-03.pdf
/Users/alice/Pictures/Photos Library.photoslibrary/originals/0/2/IMG_2114.HEIC
/Users/alice/Desktop/screenshot-2026-05-24.png
Time predicates
Spotlight understands a small DSL of relative time functions inside queries, written with a leading $. They are evaluated when the query runs, so a saved query "files changed in the last hour" stays correct.
| Function | Returns |
|---|---|
$time.now | Now |
$time.today | Midnight today |
$time.today(-N) | N days ago |
$time.yesterday | Midnight yesterday |
$time.this_week, $time.this_month, $time.this_year | Boundary dates |
$time.now(-3600) | 3600 seconds ago |
# Files modified in the last hour
mdfind "kMDItemFSContentChangeDate > \$time.now(-3600)"
# Documents created today
mdfind "kMDItemContentType == 'public.composite-content' \
&& kMDItemFSCreationDate >= \$time.today"
# Photos shot this week
mdfind "kMDItemContentTypeTree == 'public.image' \
&& kMDItemContentCreationDate >= \$time.this_week"
Output:
/Users/alice/Pictures/IMG_2231.HEIC
/Users/alice/Documents/meeting-notes-2026-05-25.md
File-type queries via UTI
macOS classifies every file by a Uniform Type Identifier (UTI) — a reverse-DNS string like public.image, com.adobe.pdf, or com.apple.application-bundle. Spotlight indexes two attributes: kMDItemContentType (the leaf UTI) and kMDItemContentTypeTree (the whole inheritance chain). Querying the tree is the right way to ask "all images regardless of format".
# All PDFs (leaf UTI)
mdfind "kMDItemContentType == 'com.adobe.pdf'"
# All images — tree match catches JPEG, PNG, HEIC, RAW, etc.
mdfind "kMDItemContentTypeTree == 'public.image'"
# All apps
mdfind "kMDItemContentType == 'com.apple.application-bundle'"
# All video files
mdfind "kMDItemContentTypeTree == 'public.movie'"
# Discover a file's UTI tree
mdls -name kMDItemContentTypeTree ~/Downloads/photo.heic
Output:
/Users/alice/Pictures/IMG_2114.HEIC
/Users/alice/Downloads/photo.jpg
/Users/alice/Desktop/screenshot.png
kMDItemContentTypeTree = (
"public.heic",
"public.heif-standard",
"public.image",
"public.data",
"public.item",
"public.content"
)
Scoping with -onlyin
Without -onlyin, mdfind searches every indexed volume — internal disk, indexed external drives, and (on default settings) the user's home directory. -onlyin DIR limits results to paths under DIR, dramatically tightening output. The flag can appear multiple times to union two scopes.
# Home directory only
mdfind -onlyin ~ "kMDItemContentType == 'public.image'"
# Just Downloads
mdfind -onlyin ~/Downloads -name "*.dmg"
# Two scopes
mdfind -onlyin ~/Documents -onlyin ~/Desktop "kMDItemFSName == '*.md'"
Output:
/Users/alice/Downloads/Firefox-117.dmg
/Users/alice/Downloads/Slack-4.40.dmg
-name shorthand
-name PATTERN is the most common ergonomic shortcut — it expands to kMDItemFSName == "*PATTERN*"cd, a case- and diacritic-insensitive substring match against the filename. It is not a glob; the asterisks are added implicitly.
mdfind -name report
# matches Report.pdf, MyReport.txt, monthly-report.md
mdfind -name "*.csv" -onlyin ~/Downloads
# matches any path containing ".csv" — including foo.csv.bak
mdfind "kMDItemFSName == '*.csv'cd && !(kMDItemFSName == '*.csv.*'cd)"
# strict: ends in .csv, with nothing after
Output:
/Users/alice/Downloads/sales-2026.csv
/Users/alice/Downloads/sales-2026.csv.bak
/Users/alice/Downloads/inventory.csv
Content search
Spotlight indexes text content for many formats (PDF, RTF, DOCX, Pages, source code, plain text). The free-text form of mdfind searches name, tags, and content together, so a bare word can hit any of them. Use the explicit kMDItemTextContent attribute to restrict the match to body text.
# Free-text — name + content + metadata
mdfind "quarterly revenue"
# Content only
mdfind "kMDItemTextContent == '*quarterly revenue*'cd"
# Content AND filename narrowing
mdfind "kMDItemTextContent == '*todo*'cd && kMDItemFSName == '*.md'cd" \
-onlyin ~/notes
Output:
/Users/alice/Documents/q1-report.pdf
/Users/alice/notes/2026-05-24.md
/Users/alice/notes/roadmap.md
Printing attributes with -attr
-attr ATTR prints the value of one attribute next to each result, useful when the bare path isn't enough — e.g. you want a list of PDFs with their page counts or photos with their EXIF resolution.
mdfind -onlyin ~/Documents -attr kMDItemNumberOfPages \
"kMDItemContentType == 'com.adobe.pdf'"
mdfind -onlyin ~/Pictures -attr kMDItemPixelWidth \
"kMDItemContentTypeTree == 'public.image'"
mdfind -onlyin ~/Downloads -attr kMDItemFSSize -name "*.dmg"
Output:
/Users/alice/Documents/q1-report.pdf kMDItemNumberOfPages = 24
/Users/alice/Documents/handbook.pdf kMDItemNumberOfPages = 312
/Users/alice/Documents/receipt-march.pdf kMDItemNumberOfPages = 1
-live mode
-live keeps the query open and prints updates as files are added or removed from the result set. The output stream stays open until Ctrl-C. Each batch is prefixed with [Tracking matched X results] or [Update X added Y removed Z]. Combine with tail -f-style consumers for a poor-man's fswatch alternative for indexed content. Pair -live with -reprint when downstream code expects the full result set on every change instead of diffs.
# Stream Downloads folder additions matching *.dmg
mdfind -onlyin ~/Downloads -live -name "*.dmg"
# Reprint the full set on every update (easier to consume from awk / a UI)
mdfind -onlyin ~/Downloads -live -reprint -name "*.dmg"
Output:
[Tracking matched 3 results.]
/Users/alice/Downloads/Firefox-117.dmg
/Users/alice/Downloads/Slack-4.40.dmg
/Users/alice/Downloads/Zoom.dmg
[Update; 4 results; 1 added; 0 removed]
/Users/alice/Downloads/MacUpdater-4.dmg
Companion: mdls — show attributes
mdls prints every Spotlight attribute Spotlight indexes for a given file, one per line. Use it to discover attribute names before writing a query — once you see what attributes the file actually carries, you can pick the right one for mdfind.
mdls report.pdf | head -20
mdls -name kMDItemContentTypeTree photo.heic
mdls -name kMDItemAuthors -name kMDItemTitle book.epub
Output:
kMDItemContentCreationDate = 2026-03-15 09:42:11 +0000
kMDItemContentModificationDate = 2026-04-10 14:07:55 +0000
kMDItemContentType = "com.adobe.pdf"
kMDItemDisplayName = "report.pdf"
kMDItemFSCreationDate = 2026-03-15 09:42:11 +0000
kMDItemFSName = "report.pdf"
kMDItemFSSize = 204812
kMDItemKind = "PDF Document"
kMDItemNumberOfPages = 24
kMDItemTitle = "Q1 Report"
Companion: mdutil — manage the index
mdutil is the administrative side of Spotlight — it reports indexing state, toggles indexing per volume, and forces a rebuild. Disabling indexing on a large external drive can save power; rebuilding the index is the first thing to try when search results have gone stale or empty.
mdutil -s / # status for root volume
mdutil -as # status for ALL volumes
sudo mdutil -i off /Volumes/Archive # disable indexing on a volume
sudo mdutil -i on /Volumes/Archive # enable
sudo mdutil -E / # erase and rebuild root index
sudo mdutil -E /Volumes/Archive # rebuild a specific volume
Output:
/:
Indexing enabled.
/System/Volumes/Data:
Indexing enabled.
/Volumes/Archive:
Indexing disabled.
Companion: mdimport — import a file or plugin
mdimport invokes a Spotlight importer manually — useful when you want a specific file (or a freshly-installed third-party importer) reflected in the index without waiting for the automatic sweep. mdimport -d 4 FILE runs in debug mode and prints the attributes the importer extracts.
mdimport ~/Documents/just-saved.pdf # add to the index now
mdimport -d 4 ~/Documents/just-saved.pdf # debug: show extracted attributes
mdimport -L # list installed importers
mdimport -X # print the schema (attributes + types)
Output:
2026-05-25 09:14:11.345 mdimport[4831] Imported '/Users/alice/Documents/just-saved.pdf'
2026-05-25 09:14:18.012 mdimport[4842]
Bundle ID = com.apple.MDImporter.PDF
Path = /System/Library/Spotlight/PDF.mdimporter
Version = 1
mdfind vs find vs fd
The three tools answer similar questions but with very different performance and scope characteristics. The right default depends on whether the location is indexed and whether you need expression filters Spotlight does not understand.
| Aspect | mdfind | find | fd |
|---|---|---|---|
| Backing data | Spotlight index | Live directory walk | Live directory walk |
| Speed on indexed content | Milliseconds (1 M files) | Seconds–minutes | Seconds |
| Works on unindexed paths | No (silent empty result) | Yes | Yes |
| Content search | Yes (built in) | No (must pipe xargs grep) | No |
| Metadata filters | Rich (Spotlight attributes) | File-system only | File-system only |
Honors .gitignore | No | No | Yes (default) |
| Cross-platform | macOS only | POSIX | Linux/macOS/Windows |
| Excludes by name | Manual query syntax | -not -name | --exclude |
| Best for | "What did I save last week?" | Portable scripts | Dev-tree file lists |
A practical rule of thumb: use mdfind for user content on the internal disk, fd inside source trees, and find when you need portability or to act on raw filesystem state (-mtime, -perm, -exec rm).
Spotlight indexing configuration
mdfind itself reads no config file — every flag is on the command line. What it can see, though, is governed by Spotlight's per-volume indexing state and a handful of opt-out sentinels. The system has migrated away from user-editable plists over the last few releases: System Settings → Spotlight → Search Privacy is now the canonical interface, and several legacy sentinel files have quietly stopped working in macOS 15+. macOS only — there is no Linux or Windows equivalent for Spotlight itself; mdfind is macOS-exclusive.
Mechanisms that affect what mdfind finds, in order of how often you'll actually use them:
| Mechanism | Location | Effect | Status (macOS 15 Sequoia / 26 Tahoe) |
|---|---|---|---|
| System Settings → Spotlight → Search Privacy | GUI; data written to per-user prefs | Adds paths/volumes to the exclusion list; Spotlight refuses to index or surface them | ✅ Canonical method — Apple's recommended interface |
.noindex directory suffix | Appended to any folder name | The folder and everything under it is excluded from indexing | ✅ Still works |
mdutil -i off /Volumes/X | Per-volume state file managed by mdutil | Disables indexing for an entire volume | ✅ Still works; persisted in /.Spotlight-V100/_IndexPolicy.plist |
~/Library/Preferences/com.apple.Spotlight.plist | Per-user prefs | Stores user Spotlight choices (categories enabled, etc.); managed by the System Settings pane | ✅ Read by Spotlight, but edit via System Settings — direct edits often reverted |
/.Spotlight-V100/VolumeConfiguration.plist | Per-volume, written by Spotlight | Stores per-volume indexing rules (exclusions, last index time) | ⚠️ Not user-editable in modern macOS — Apple owns this file |
.metadata_never_index (empty file at volume root) | /.metadata_never_index on the target volume | Historically disabled indexing for that whole volume | ❌ No longer obeyed as of macOS 15 (Sequoia) — use Search Privacy or mdutil -i off instead |
.metadata_never_index_unless_rootfs | Same as above, with rootfs override | Historically disabled indexing unless the volume booted the OS | ❌ Also no longer obeyed in macOS 15+ |
Precedence and override order when multiple settings conflict:
mdutil -i off VOLUME— kills indexing for the whole volume; overrides everything below.- System Settings → Search Privacy entries — exclude specific paths regardless of
.noindexmarkers. .noindexdirectory suffix — excludes one folder subtree.- Default Apple-excluded paths —
~/Library(most subfolders),/private,/var,/tmp,.gitand any dot-directory under indexed scope. - Everything else gets indexed.
# Inspect what's currently configured
# Volume-level indexing state (all volumes)
mdutil -as
# Per-volume policy file Apple manages
sudo plutil -p /.Spotlight-V100/VolumeConfiguration.plist 2>/dev/null | head -30
# Per-user Spotlight preferences (categories, suggestions)
plutil -p ~/Library/Preferences/com.apple.Spotlight.plist | head -20
# Find every .noindex folder in your home directory
find ~ -type d -name "*.noindex" 2>/dev/null
Output:
/:
Indexing enabled.
/System/Volumes/Data:
Indexing enabled.
/Volumes/Archive:
Indexing disabled by user.
Macros and rebuild scope — when you force a rebuild with mdutil -E /, modern macOS treats / and /System/Volumes/Data as separate APFS volumes that both need addressing. The boot volume holds OS-only metadata; user files live under /System/Volumes/Data. Rebuild both, in that order:
sudo mdutil -E /
sudo mdutil -E /System/Volumes/Data
Output:
/:
Indexing and searching disabled.
/System/Volumes/Data:
Indexing and searching disabled.
(Both volumes immediately re-enable indexing and begin rebuilding in the background; the disabled message is momentary.)
Annotated example: opt out of indexing for a backup drive
# Hard opt-out: turn off indexing for an external archive drive
sudo mdutil -i off /Volumes/Archive
sudo mdutil -d /Volumes/Archive # also delete its existing index
# Soft opt-out: exclude one folder under an indexed drive
mv ~/Builds ~/Builds.noindex # folder rename = instant exclusion
# Per-app: exclude scratch directories under your home
mkdir ~/scratch.noindex
Output: (none — exits 0 on success)
Common pitfalls
- No results from a path you can see — Spotlight indexing is off or has not finished. Check with
mdutil -s /pathand rebuild withsudo mdutil -E /pathif needed. - Hidden / system directories missing — Spotlight excludes anything under
~/Library,/private, and many dot-directories by default. Either add them in Spotlight Privacy settings (in reverse — remove from the exclude list) or fall back tofind. - Unindexed external drives return nothing — as of macOS Sequoia 15.1, Spotlight indexing is enabled by default on every mounted volume (the opposite of pre-15.1 behaviour, which silently surprised many users who relied on external drives staying unindexed). Verify with
mdutil -as; opt out withsudo mdutil -i off /Volumes/MyDriveor via System Settings → Spotlight → Search Privacy. On macOS 14 and earlier, the inverse advice applies — opt in withsudo mdutil -i on /Volumes/MyDriveand wait for the first index to finish. -name foonot findingfoo.txt—-namedoes substring with implicit wildcards, but it is case-insensitive only against the FS-name attribute. Multi-byte names sometimes need[cd]in a structured query, e.g.mdfind "kMDItemDisplayName == '*foo*'cd".- Query quoting — the structured query string is parsed by
mdfind, not by the shell. Always wrap the whole query in single quotes; inside it, single quotes delimit string values, and\$time.todayneeds a backslash so the shell does not expand the variable. - Free-text and content can mismatch —
mdfind alicesearches name + content + tags together;mdfind "kMDItemTextContent == '*alice*'cd"searches only body text. The latter is what you want when grepping documents. -livenever returns — it is meant to stay open and stream changes. Pipe it throughhead -n Nor wrap intimeout 30 mdfind -live …if you only want a snapshot.- Spotlight does not index
.git— for source-code search, preferripgreporgit grep;mdfindwill skip everything under any directory whose name starts with a dot. kMDItemKindreturns localized strings —mdfind "kMDItemKind == 'Application'"returns nothing on a non-English macOS, becausekMDItemKindis the human-readable, locale-dependent string Spotlight surfaces in the GUI (Applicazionein Italian, character-set equivalents in Chinese / Japanese). For portable cross-locale scripts, always query by the language-invariant UTI instead:mdfind "kMDItemContentType == 'com.apple.application-bundle'"ormdfind "kMDItemContentTypeTree == 'public.image'". This bites scripts shipped to international fleets and is still undocumented as of macOS 26 (Tahoe).
Real-world recipes
Find every PDF over 10 MB modified this month
A common cleanup task — combine UTI, size, and date predicates into one query, then sort by size with a small pipeline.
mdfind -onlyin ~/Documents -attr kMDItemFSSize \
"kMDItemContentType == 'com.adobe.pdf' \
&& kMDItemFSSize > 10485760 \
&& kMDItemFSContentChangeDate >= \$time.this_month" \
| sort -k3 -n -r
Output:
/Users/alice/Documents/handbook.pdf kMDItemFSSize = 52428800
/Users/alice/Documents/whitepaper.pdf kMDItemFSSize = 31457280
/Users/alice/Documents/q1-report.pdf kMDItemFSSize = 12582912
Delete every .DS_Store everywhere
Spotlight indexes .DS_Store files, so mdfind plus xargs -0 is faster than find for whole-disk cleanups.
mdfind -0 -name ".DS_Store" | xargs -0 rm -v
Output:
/Users/alice/Documents/.DS_Store
/Users/alice/Desktop/.DS_Store
/Users/alice/Pictures/.DS_Store
Find duplicate filenames across the home directory
Print just the filename component and pipe through sort | uniq -d to surface filenames that appear in more than one path — the starting point of a manual de-dupe.
mdfind -onlyin ~ "kMDItemContentTypeTree == 'public.image'" \
| awk -F/ '{print $NF}' \
| sort | uniq -d
Output:
IMG_2114.HEIC
screenshot.png
vacation.jpg
Photos shot on a specific date
kMDItemContentCreationDate is the EXIF capture time, not the filesystem date — it survives copy-and-paste and remains correct after a Photos library export.
mdfind "kMDItemContentTypeTree == 'public.image' \
&& kMDItemContentCreationDate >= '2026-05-01' \
&& kMDItemContentCreationDate <= '2026-05-31'"
Output:
/Users/alice/Pictures/IMG_2114.HEIC
/Users/alice/Pictures/IMG_2115.HEIC
/Users/alice/Pictures/IMG_2116.HEIC
Open the most recently modified file matching a query
Combine mdfind with -attr kMDItemFSContentChangeDate, sort descending, then open the first result. Useful for "open the latest screenshot I just took".
mdfind -onlyin ~/Desktop -attr kMDItemFSContentChangeDate \
"kMDItemFSName == 'Screenshot*'cd" \
| sort -k3 -r | head -1 | awk -F' *' '{print $1}' | xargs -I{} open {}
Output: (none — opens the file in Preview)
Diff Spotlight count against find count
Useful as a quick "is my index fresh?" check. If Spotlight's count drifts from a directory walk, the index is stale — rebuild it.
echo "Spotlight: $(mdfind -onlyin ~/Documents -count \
"kMDItemContentType == 'com.adobe.pdf'")"
echo "find: $(find ~/Documents -type f -iname '*.pdf' | wc -l | tr -d ' ')"
Output:
Spotlight: 184
find: 186
Watch a download folder for completed installers
-live plus a small filter gives a streaming notifier — every time a .dmg or .pkg finishes downloading, the path is appended.
mdfind -onlyin ~/Downloads -live \
"kMDItemContentTypeTree == 'public.archive' \
|| kMDItemContentType == 'com.apple.disk-image-udif' \
|| kMDItemContentType == 'com.apple.installer-package-archive'"
Output:
[Tracking matched 6 results.]
/Users/alice/Downloads/Slack-4.40.dmg
/Users/alice/Downloads/Firefox-117.dmg
…
[Update; 7 results; 1 added; 0 removed]
/Users/alice/Downloads/Postgres-16.1.dmg
Save a query as a shell function
The query syntax is verbose for repeated use. Wrap the common ones in zsh / bash functions so they read like proper subcommands.
# In ~/.zshrc
recent() { # files changed in the last N hours
local hours=${1:-24}
mdfind -onlyin "$HOME" \
"kMDItemFSContentChangeDate > \$time.now(-$((hours*3600)))"
}
bigpdfs() { # PDFs over N megabytes
local mb=${1:-10}
mdfind -onlyin "$HOME" -attr kMDItemFSSize \
"kMDItemContentType == 'com.adobe.pdf' && kMDItemFSSize > $((mb*1048576))"
}
Output: (none — functions defined; call as recent 6 or bigpdfs 50)
Spotlight's query parser does not understand shell globs —
mdfind "*.pdf"matches nothing useful. Either use the-nameshortcut (mdfind -name "*.pdf") or the structured form (mdfind "kMDItemFSName == '*.pdf'c"). The bare quoted free-text form is a content search, not a glob.
To browse Spotlight attributes interactively, run
mdimport -X | less— it dumps the entire attribute schema (name, type, description) for every importer installed on the system. Use it as the canonical reference when you don't know what attribute holds a particular piece of metadata.
Sources
References consulted while writing and updating this article. Links open in a new tab. Order is curated by relevance — sorting is intentionally disabled (data-no-sort).
| Source | Why cited |
|---|---|
| Using and troubleshooting Spotlight in Sequoia — Eclectic Light Co. | November-2024 summary confirming that .metadata_never_index no longer works in macOS 15, plus the /System/Volumes/Data rebuild scope used in the configuration section. |
| Spotlight on search: How Spotlight works — Eclectic Light Co. | Architectural background on the index, importers, and VolumeConfiguration.plist referenced in the configuration mechanism table. |
| Spotlight indexing enabled for all volumes after 15.1 update — MacRumors Forums | Primary evidence for the macOS 15.1 default-flip on removable-media indexing, used to correct pitfall #3. |
| What's new in macOS Tahoe 26 — Apple Support | Authoritative Apple changelog confirming the macOS 26 (Tahoe) Spotlight menubar redesign that motivated the "What it is" version note. |
| Spotlight on Mac: Advanced new features in macOS 26 Tahoe — Cult of Mac | Coverage of the Applications/Files/Actions/Clipboard buttons and quick-key shortcuts referenced in the version note. |
| Disable Spotlight on newly mounted media — Apple Community | Cross-check of the modern opt-out flow (mdutil -i off + Search Privacy) after the sentinel-file deprecation. |
| Providable 1.2 works on non-English systems — Eclectic Light Co. | January-2026 deep dive documenting that kMDItemKind returns localized strings (Italian Applicazione, etc.) on macOS Tahoe, supporting the new locale-invariant-UTI pitfall added in this revision. |