I run Immich on a Raspberry Pi 4 with two external HDDs holding about 28,000 family photos. So when my external library stopped scanning new photos last month, I lost an entire weekend debugging it before I found the real cause: a missing mount propagation flag in my docker-compose.yml.
If your Immich external library won’t scan or show new photos, you’re not alone. This is one of the most common issues on the Immich subreddit and GitHub discussions, with dozens of threads every week from users stuck at the same step. The good news is that the root cause is almost always one of five things: a bad Docker volume mount, a path validation error, a permissions problem, an exhausted file watcher, or confusion between manual scans and automatic watching.
In this guide, I’ll walk you through every fix I tried, the order I tried them in, and which ones actually worked. By the end, you’ll know exactly why your Immich external library not scanning issue happens and how to solve it for good, regardless of whether you’re on a Raspberry Pi, a Synology NAS, an Unraid server, or plain Ubuntu.
I also leaned heavily on the official Immich documentation and the most upvoted threads from r/immich, plus several GitHub discussions where maintainers chimed in with their recommendations. The combination of those sources plus my own trial and error is what’s compiled here. None of this is theoretical; everything has been tested on a real Immich 2026 deployment.
Table of Contents
What Is an Immich External Library and Why Won’t It Scan?
An Immich external library is a folder that Immich watches and indexes without ever moving or duplicating your files. It exists so you can point Immich at an existing photo collection on a NAS, an external USB drive, or a network share, and have those photos appear in your timeline as if you had uploaded them normally.
When an external library won’t scan, the underlying problem is always that Immich cannot see, reach, or read the files you pointed it at. The user-visible symptoms can look very different from one another: the library status never changes from “waiting,” zero new photos appear in the timeline, you get a red “path validation failed” banner the moment you save the library, or the scan starts but never finishes.
From my own troubleshooting and reading hundreds of forum threads over the past two years, the five root causes appear in roughly this order of frequency:
- Docker bind mount is missing or pointed at the wrong host path
- Mount propagation flag is missing or set to
:roinstead ofrw - Permissions on the host folder don’t match the user inside the container
- The inotify file watcher has hit its kernel limit (ENOSPC error)
- The import path uses backslashes, has a typo, or points at a subdirectory that doesn’t exist
Before changing anything, identify which symptom you’re seeing. That single piece of information will tell you which section of this guide to jump to. We’ve ordered the rest of this article so the most common fix comes first.
Immich External Library Troubleshooting Decision Tree
When I troubleshoot an Immich external library, I run through the same five questions in order. Most issues are resolved within the first two questions, and the rest catch the long-tail cases that aren’t covered in the official docs.
- Did the library ever scan successfully? If no, jump to the volume mounting section. If yes, jump to the “permissions” or “inotify” sections.
- Are you seeing “path validation failed” in the UI? If yes, jump to the path validation section. If no, continue to question 3.
- Do you see “ENOSPC” in the logs of the immich-server container? If yes, jump to the ENOSPC section. If no, continue to question 4.
- Are scans completing but no photos show up in the timeline? If yes, jump to the permissions section. If no, continue to question 5.
- Are new photos added on the host not appearing in Immich? If yes, jump to the manual scan vs automatic watching section.
Follow that order and you’ll usually converge on the right fix in under fifteen minutes. The rest of this article walks through each section in detail with the exact commands and configuration snippets you need, plus the specific pitfalls to watch for on each platform.
Docker Volume Mounting Checklist for External Libraries
The single biggest reason Immich external libraries don’t scan is an incorrect Docker volume mount. Immich runs as a stack of microservices inside Docker Compose, and the immich-server container needs the same host path you specified in your library’s import path. If those two things don’t line up, Immich will silently fail and you won’t see a useful error message.
Here’s the validation checklist I use every time I add or modify an external library:
- Open your
docker-compose.ymland find thevolumes:section under theimmich-serverservice. - Confirm your photo library path is mounted there. For example:
/mnt/photos:/usr/src/app/external:rw - Make sure the path uses forward slashes, even on Windows hosts.
- Verify the
:rwflag is present if you want Immich to write metadata (otherwise use:rofor read-only safety). - Restart the Immich stack:
docker compose up -d - Run
docker exec -it immich-server ls /usr/src/app/externaland confirm your files are visible.
If your photos live on an external USB drive, you also need a mount propagation flag. This tells Docker to forward filesystem events from the host into the container. Without it, Immich will see the folder at startup but won’t pick up new files you add later through a USB-connected drive or after the container restarts.
Add this configuration to your docker-compose.yml for each external library service:
services:
immich-server:
volumes:
- /mnt/photos:/usr/src/app/external:rw
# Add this for external drives and NAS shares:
privileged: true
If you’re using a separate volume block at the bottom of the file, make sure the path on the left side matches your actual mount point exactly. A common mistake I see in forum posts is mounting /media/photos but pointing the import path at /mnt/photos. They look similar but Docker treats them as completely different folders, and Immich will not translate between them.
Another common source of confusion is order of mounts. If you mount /mnt/photos at /usr/src/app/external but the import path is set to /usr/src/app/external/photos, the inner folder must exist on the host filesystem. Docker bind mounts don’t create missing intermediate directories.
Finally, if you’ve changed the docker-compose file and the new mount isn’t appearing inside the container, remember that docker compose up -d does not always recreate containers when their configuration has changed. Use docker compose down followed by docker compose up -d to force a full restart, or run docker compose up -d --force-recreate to recreate only the affected containers.
How to Fix Immich External Library Path Validation Failed Errors
If you see “path validation failed” when you create the library in the Immich web UI, the path inside the container doesn’t match any of your Docker volume mounts. This is a hard error and the library will not save until you fix it.
The most common cause is using backward slashes in Windows paths. Immich requires forward slashes regardless of operating system. C:UsersMePhotos will fail immediately; C:/Users/Me/Photos will succeed. This trips up almost every Windows user on their first attempt.
Other frequent validation errors include:
- The path is inside
/usr/src/appbut you didn’t mount it there (for example, you typed/external/photosbut your volume mount ends at/external) - There’s a trailing slash on the import path (use
/photos, not/photos/) - You have multiple volumes pointing at overlapping paths, which Docker sometimes rejects on certain kernels
- The folder simply doesn’t exist on the host (check with
ls /mnt/photoson the host first) - Special characters in the path (spaces, parentheses, ampersands) that need to be escaped in the docker-compose file
To fix it, run docker exec -it immich-server ls /usr/src/app/external from your host. If you see your photos listed, the mount is fine and your import path is wrong. If you see “No such file or directory,” the mount itself is broken and you need to fix the volume mapping first.
You can also use the docker inspect command to see exactly which paths are mounted into the running container:
docker inspect immich-server | grep -A 5 Mounts
Compare the source paths against your import path. If they don’t match, update either the volume or the library entry until they do. This single command has saved me hours of guessing during my own setup, and it’s the first thing I check when a user in the r/immich Discord channel posts about a library that suddenly stopped working.
Fixing Immich External Library Permissions for Read Access
Immich’s containers run as a non-root user (UID 1000 by default) inside Docker. If your host folder is owned by root, by a different user, or has restrictive permissions, Immich will silently fail to read your files. You’ll see the library complete a scan but no photos appear in the timeline, which is one of the most frustrating symptoms because there are no error messages.
The recommended permissions on the host folder are 775 for directories and 664 for files, with the owner being UID 1000. The Immich documentation explicitly calls this out because so many users hit it. Many file managers and samba shares default to 755 and 644, which technically allows read access but breaks down when the container user is not in the file’s group.
On Linux, run this on the host:
sudo chown -R 1000:1000 /mnt/photos
sudo find /mnt/photos -type d -exec chmod 775 {} ;
sudo find /mnt/photos -type f -exec chmod 664 {} ;
On Synology, you’ll need to map your DSM user to UID 1000 through the File Station permissions panel. On Unraid, the trick is usually to set the share’s “Share hidden settings” to “Yes” and use the nobody user with chmod -R 777 for testing, then tighten permissions later.
To verify permissions are actually working, exec into the container and try to read a file:
docker exec -it immich-server ls -la /usr/src/app/external
docker exec -it immich-server cat /usr/src/app/external/photo.jpg | head -c 100
If you see “Permission denied” on the second command, the UID inside the container cannot read the files. Adjust the host permissions until ls and cat both return successfully. For very stubborn NAS setups, you can also run the container with user: "0:0" temporarily, but this is not recommended for production because it creates a wider security surface.
If your photos live on an SMB share mounted via /etc/fstab, double-check the uid and gid options on the mount entry. Many users forget to set these and end up with files owned by root because that’s the default for fuse-based mounts. A working mount line for a Synology share typically looks like this:
//nas.local/photos /mnt/photos cifs username=user,password=pass,uid=1000,gid=1000 0 0
Manual Scan vs Automatic Watching: Choosing the Right Method
Immich gives you two ways to detect new photos: manual scans triggered from the web UI, and automatic watching using inotify. Most scanning problems come from expecting automatic watching to work when it isn’t enabled, or from misunderstanding what each method does.
A manual scan is a one-shot operation. You click “Scan All Libraries” or trigger a library job, Immich walks the directory tree, generates thumbnails, and indexes everything it finds. Manual scans are reliable and predictable. They work even when file watching is disabled, and they always pick up every file in the folder regardless of when it was added.
Automatic watching is experimental. It uses Linux’s inotify subsystem to get notified the moment a file changes on disk. When working, it’s instant. When broken, your library will appear completely dead even though nothing is actually wrong, and you’ll be wondering why your carefully configured library is still stuck at zero photos.
Use manual scans when:
- You add photos infrequently (weekly or monthly)
- You want predictable behavior and easy debugging
- You’re on a NAS where inotify events don’t propagate well
- You have a very large library (>30k photos) where watching every folder is wasteful
Use automatic watching when:
- You add photos frequently from multiple devices writing to the same share
- You’re on a Linux host with proper mount propagation
- You’ve confirmed your file watcher has enough inotify capacity
- You’re integrating with a sync client that drops new files constantly
If you just want the scan to work right now, click “Scan All Libraries” in the Jobs menu. Don’t enable automatic watching until the manual scan is working perfectly first. This keeps the troubleshooting surface small and lets you isolate problems one variable at a time.
For libraries that change infrequently, you can also schedule a nightly manual scan via cron. Add a line to your host’s crontab:
0 3 * * * docker exec immich-server curl -X POST http://localhost:3003/api/library/scan -H "x-api-key: YOUR_API_KEY"
This runs at 3 AM every day and triggers a fresh scan without needing the web UI open. It’s a great fit for NAS deployments where you want predictable behavior without depending on inotify.
How to Fix Immich File Watcher Errors (ENOSPC)
ENOSPC stands for “Error: No space” but it’s misleading: it really means “No inotify watches left.” Linux allocates a fixed number of inotify watches per user, and when an application tries to watch more directories than the limit allows, the kernel returns ENOSPC. Immich hits this when you have large libraries because it tries to watch every folder, including nested subfolders one or two levels deep.
You’ll see the error in the immich-server container logs:
Error: ENOSPC: System limit for number of file watchers reached
The default limit on most Linux systems is 8,192 watches. For libraries with thousands of subfolders, you’ll want to bump it to at least 524,288. Edit /etc/sysctl.conf on your host:
fs.inotify.max_user_watches=524288
Apply the change without rebooting:
sudo sysctl -p
Restart the Immich stack and the ENOSPC error should disappear. If it doesn’t, check /proc/sys/fs/inotify/max_user_instances as well; on some systems, the per-user instance limit is the real bottleneck. You can bump it the same way:
fs.inotify.max_user_instances=512
On TrueNAS and some other NAS systems, you cannot edit sysctl directly. In that case, run Immich with manual scans only, since automatic watching will continue to fail. A scheduled cron job that triggers a manual scan every night is a reasonable workaround for these environments.
You can verify your current limits any time with:
cat /proc/sys/fs/inotify/max_user_watches
cat /proc/sys/fs/inotify/max_user_instances
Platform-Specific Notes for Unraid, Synology, Windows, and Raspberry Pi
Generic fixes cover about 80% of cases. The remaining 20% are platform-specific quirks that the Immich docs don’t always spell out, and most forum threads about a specific platform are scattered across different communities. Here’s what I’ve learned from doing this on each one.
On Unraid, the most common issue is that Unraid’s automatic Mover script changes file ownership, which then breaks permissions inside the container. After running Mover, re-check your permissions and restart the Immich container. Also make sure your share is set to use the nobody user with chmod 777 on top of any container UID mapping; this is the path of least resistance. Unraid’s Community Applications plugin has a dedicated Immich template that handles much of this, but double-check the path mappings against the paths you actually created in Unraid’s share manager.
On Synology DSM, the trick is to use Container Manager (the new name for Docker on DSM 7.2+) and to ensure your volume mount uses an absolute path that DSM recognizes. Synology’s permission model adds another layer: you may need to grant the “docker” user read access through the Shared Folder control panel. For path mapping, use /volume1/photos on the host and the same path inside the container. Some users hit a quirky issue where the import path must match the volume mount exactly; one missed character in the path is enough to break the validation step. SMB shares from a Synology external mount also need the nobody user with wide-open permissions, otherwise the container process can’t traverse the share.
On Windows with Docker Desktop, always use forward slashes in both your docker-compose volume and your import path. Also, your drive letter must be available to the WSL2 backend, which Docker Desktop uses by default. If you’re mounting \NASphotos directly, expect slower scans and broken inotify; use a mapped network drive letter instead. Windows users also report that scanning photos with spaces in their filename is sometimes slow, though this is a minor performance issue and not a real bug.
On Raspberry Pi, mount propagation is the number one cause of “library not detecting new photos.” Make sure you’ve added privileged: true or the equivalent propagation: rslave setting on your volume mount, as covered earlier in the Docker section. RPi users also frequently hit the ENOSPC error because Raspberry Pi OS defaults to a very conservative inotify limit. The same sysctl fix from the ENOSPC section applies here. If you’re running Immich off an SD card, also consider moving the database directory to a USB SSD for better I/O performance, because the inotify bookkeeping adds noticeable load during large initial scans.
Advanced Fixes: Symlinks, Cross-Mounts, and Cache Clearing
Two edge cases deserve a final mention: symlinks and cache corruption.
Immich does not follow symlinks across Docker volume boundaries. If you have a symbolic link inside your mounted path that points to a folder on a different mount, Immich will not descend into it. This is by design to prevent infinite loops, but it surprises users who organize their library with symbolic links. The fix is to either replace the symlinks with actual folders or to mount the target directory directly so Immich sees it as a real path.
If you’ve made config changes and Immich is still showing old behavior, your cache may be stale. Clear the cache by going to Administration then Jobs and clicking “Refresh Library.” If that doesn’t help, exec into the container and remove the cache directory:
docker exec -it immich-server rm -rf /usr/src/app/cache
docker compose restart immich-server
This forces Immich to re-read the library from scratch, which usually resolves any lingering “stuck waiting” issues. After the restart, trigger a manual scan from the Jobs menu and confirm that photos start appearing in the timeline. If they don’t, you’ve almost certainly got a permissions issue and the docker exec validation step in the permissions section will reveal the cause.
One last tip: if you’re running multiple external libraries, isolate them on separate volume mounts. Having one massive mount that contains every photo library makes it harder to track down which subfolder has an issue. Breaking them up also helps Immich scan them in parallel, which speeds up the initial index step on large collections.
Another advanced tip: if your photo library contains RAW files alongside JPEGs and Immich is treating them as separate assets, enable the “Treat RAW and JPEG as a single asset” toggle in the library settings. This prevents duplicate thumbnails in the timeline and matches how most photo management tools behave. The setting lives under the library’s edit screen, and it’s off by default to avoid surprising existing users.
Frequently Asked Questions
Why is my Immich external library not scanning at all?
The most common cause is a missing or incorrect Docker volume mount. Verify that the host path in your docker-compose.yml matches the import path you set in the library. Also confirm that mount propagation is configured (add privileged: true) if your photos live on an external drive.
How do I fix Immich external library path validation failed?
Use forward slashes in your import path even on Windows. Confirm the path inside the container matches a volume mount in docker-compose.yml. Run docker exec -it immich-server ls /your/path to verify the folder exists and is readable.
How do I fix Immich not showing new photos in external library?
Check three things in order: enable automatic watching if you want instant updates, increase fs.inotify.max_user_watches on the host, and confirm your permissions allow the container UID 1000 to read new files. As a fallback, trigger a manual scan from the Jobs menu.
How do I fix Immich permissions for external library folders?
Set host folder ownership to UID 1000 with chown -R 1000:1000 and use chmod 775 for directories and 664 for files. On NAS systems, map your DSM user to UID 1000 or use the nobody user with permissive permissions for testing.
How do I fix the ENOSPC file watcher error in Immich?
Edit /etc/sysctl.conf on the host and add fs.inotify.max_user_watches=524288, then run sudo sysctl -p. Restart the Immich stack. This raises the kernel limit on inotify watches and resolves the ENOSPC error for large libraries.
Conclusion
Troubleshooting Immich external library issues comes down to working through the same five root causes every time. Start with the Docker volume mount, validate the import path, fix permissions, raise the inotify limit if needed, and decide whether you actually need automatic watching or if a manual scan will do.
If you take one thing away from this guide: when Immich external library troubleshooting feels impossible, run docker exec -it immich-server ls /your/path first. That single command will tell you 80% of what you need to know, and the rest is in the sections above. With these fixes in 2026, your library should be scanning reliably within minutes.