Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

PSA: My Unraid server with no cache pool quietly split my Docker install and ate a database

Featured Replies

Hi Everyone, this is just a public service annoucement based off the Unraid adventures I was in this past week. Last week my server came apart: a Postgres database vanished, Docker's image store split across two array disks, every container's autostart toggle turned itself off, docker exec broke engine-wide, and almost ran out of memory. I narrowed it down to a postgresql17 install where I left the default /mnt/cache/appdata/postgresql17 as the default data path.

Part 1:

My server has no cache pool, but my appdata, system, and domains shares all carried the default setting: Use cache: Prefer, pool name cache. This idles harmlessly... right up until something creates a plain directory at /mnt/cache. In my case, a container template did it — one whose author shipped /mnt/cache/appdata/postgresql17 as the default data path ("for best performance, keep the files on cache drive"). On a pool-less server, /mnt/cache is a directory on the root filesystem, which is RAM. That postgres container's entire database was in RAM and I had no idea — /mnt/user paths kept working, the GUI showed nothing odd. Then the server rebooted, and the database ceased to exist. No error, no log line, nothing to fsck. Just gone.

If you have any template with a direct /mnt/cache/... (or any /mnt/<poolname>/...) host path on a server where that pool doesn't exist, you may have data in RAM right now:

ls -ld /mnt/cache 2>/dev/null && stat -f -c %T /mnt/cache

grep -l "/mnt/cache" /boot/config/plugins/dockerMan/templates-user/*.xml

tmpfs from that stat = everything under it dies at reboot.

This part of code simulates creating a directory at /mnt:

root@Server:~# mkdir /mnt/ramtest        # same thing Docker does for a missing host path

root@Server:~# findmnt -T /mnt/ramtest -o TARGET,SOURCE,FSTYPE,SIZE

TARGET SOURCE       FSTYPE  SIZE

/mnt   rootfs[/mnt] rootfs 31.3G        <- the "31.3G disk" is half my RAM (tmpfs default)

root@Server:~# stat -f -c "%n -> type=%T fsid=%i" /mnt/ramtest /

/mnt/ramtest -> type=tmpfs fsid=d9358cadf96e294

/            -> type=tmpfs fsid=d9358cadf96e294   <- same filesystem as the OS's RAM root

root@Server:~# dd if=/dev/zero of=/mnt/ramtest/test.bin bs=1M count=512

root@Server:~# rm -r /mnt/ramtest        # clean up after yourself

  • Watch free -m while that dd runs: the "shared" column climbs by exactly 512 MB and falls back the moment you delete the file. No disk anywhere in the chain. Everything written there is erased with the rest of rootfs at reboot.

  • (The test dir is deliberately named ramtest, not cache — on a pool-less box with default share settings, creating a directory literally named /mnt/cache is the very act that arms the mover trap described below. Any name demonstrates the mechanism; that's rather the point.)

Part 2:

The mover's validity check for a prefer-share's pool is this line from /usr/local/sbin/mover:

if [[ -n $shareCachePool && -d "/mnt/$shareCachePool" ]]; then

-d. "Is it a directory." Not "is it a mountpoint," not "is it a real pool." So once that RAM directory existed, my nightly mover run began trying to move appdata and system files from the array into /mnt/cache (i.e. an unintended RAM disk). I got lucky, the mover skips files that are open (my containers were running, holding most things open), and large copies into tmpfs failed — between the open-file skips and the failed copies. I'm sure I lost some data, but I don't know what.

Part 3:

The system share, with no pool to consolidate onto, had spread across two array disks over time — so /mnt/disk2/system/docker and /mnt/disk3/system/docker both existed, same names, different contents. At every service start Unraid quietly dereferences /mnt/user/system/docker setting to one real disk — you can watch it happen in /usr/local/sbin/mount_image, which asks shfs for the system.LOCATION xattr and bind-mounts that disk's copy onto /var/lib/docker.

Which disk wins gets recomputed at every start. After a reboot, mine flipped to the stale copy. The symptoms were weird: docker images returned nothing while docker info insisted there were many images; my autostart settings disappeared (the unraid-autostart file lives inside the docker root — mine was on the other disk); containers died with "no such volume"; and because the GUI keeps writing some files through /mnt/user (which allocation routes to the other disk), the two copies kept diverging. The user-share view at /mnt/user merges both copies and looks perfectly healthy the entire time. The union view actively hid the split.

Here are some commands you can run. If you have one line from the first command: you're fine. More than one: you have the precondition, and the second command tells you which copy your engine would bind to at the next service start.

ls -d /mnt/disk*/system/docker /mnt/*/system/docker 2>/dev/null

getfattr -n system.LOCATION --only-values --absolute-names /mnt/user/system/docker; echo

The fix:

1. Shares tab → any share naming a nonexistent pool → Primary storage: Array, Secondary: None (or actually create the pool it names).

2. Kill any plain directory squatting at /mnt/<poolname> (rescue its contents first — they're in RAM, on borrowed time).

3. Fix templates with direct paths to nonexistent pools.

4. Docker directory re-pointed at an explicit disk path. If your docker folder exists on multiple disks: that's a bigger evening — consolidate to one location on purpose, ideally an explicit disk/pool path.

TL;DR

ls /boot/config/pools/                                      # pools that actually exist

grep -H shareCachePool /boot/config/shares/*.cfg             # pools your shares THINK exist

ls -ld /mnt/cache 2>/dev/null && stat -f -c %T /mnt/cache    # tmpfs = RAM trap is armed

ls -d /mnt/disk*/system/docker 2>/dev/null                   # >1 line = docker split-brain risk

grep -l "/mnt/cache" /boot/config/plugins/dockerMan/templates-user/*.xml   # templates writing to /mnt/cache

  • Community Expert

sounds like you have something mapped using /mnt/cache which would have wrote to RAM since you dont actually have a pool named cache and lost upon a reboot. This would be simply due to a pre-defined path in a container template most likely.

the real PSA is always check your paths.

Edited by MowMdown

  • Community Expert

Please post diagnostics

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.