SparkBox/Guides/Immich database "missing" restore loop

Immich Thinks Its Database Vanished and Starts Restoring It — Here's What's Really Going On

Mid-upgrade, Immich (or a helper container it spawns) logs something like a storage migration deciding your database is "missing or empty" and kicks off a restore you never asked for. People land here searching for an Immich DNS problem because the fallout looks like a connection failure — but the actual cause is a volume mount that never made it into the helper container.

Immich — your own private Google Photos, on your box
Immich — your own private Google Photos, on your box

Rather not audit container mounts by hand? SparkBox keeps every helper and maintenance container on the exact same storage paths as the app it belongs to, so a migration step never gets a partial view of your data. See the walkthrough →

The 10-second version: A helper Alpine container running a storage migration (migrate_dir_to_pool) mounted /opt and the Docker socket, but not the actual data volume, for example /volume1. From inside that container, the Immich database folder looked empty, so the migration logic assumed the data was gone and started restoring it. Fixing the mount so the helper sees the same storage path as your main Immich containers stops the false trigger.

Why This Looks Like a DNS Issue (But Isn't)

Search engines and forum threads get flooded with "Immich DNS" because of what happens after the false restore kicks off. Once a migration or restore step interrupts the stack, containers that depend on the database or the storage backend can throw errors that sound network-related — refused connections, timeouts, "could not reach host" style messages. If you're used to troubleshooting Docker networking, that pattern screams DNS resolution failure between containers.

Pi-hole blocking ads for every device on the network
Pi-hole blocking ads for every device on the network

It isn't. Docker's internal DNS, which lets containers find each other by service name, is almost never the actual fault here. The real problem happened one layer earlier: a helper container was given an incomplete view of the filesystem, misjudged the state of your data, and acted on that bad judgment. The connection errors you're seeing are downstream symptoms of that, not the cause.

The Real Cause: A Mount Missing From the Helper Container

Immich has historically used a storage migration step, often referred to by the function name migrate_dir_to_pool, to reorganize how photos and videos are laid out on disk. To do this safely with correct file ownership, that step is sometimes carried out by a short-lived helper container rather than the main Immich service.

Portainer container management on a SparkBox server
Portainer container management on a SparkBox server

In the case behind this guide, that helper container was set up with two mounts:

  • A mount for /opt, presumably for scripts or configuration the migration step needs
  • Access to the Docker socket, so it can talk to the Docker daemon and interact with other containers

What it did not have was a mount for the actual data volume — /volume1 on the system this was diagnosed on, but this could be whatever host path your Immich library and database actually live on (common on NAS devices where shares are exposed under a fixed volume name).

Docker doesn't automatically share mounts between separate containers just because they're related to the same app. Every container that needs to read or write your Immich data has to be given that mount explicitly, every time it's defined — including one-off helper containers created for a single migration task.

Because the helper container's filesystem view never included the real data path, the migration logic looked for the database where it expected to find it, saw an empty or nonexistent directory, and concluded the database was missing. Its response was to restore from backup — which is the correct behavior if the data genuinely disappeared, and the wrong behavior when the data was simply never visible to that container in the first place.

How to Check If This Is Happening to You

  1. Look for a short-lived or unfamiliar container in your container list around the time the issue started — often a small Alpine-based image, not your main Immich server or Postgres container.
    docker ps -a
  2. Inspect its mounts and compare them to your main Immich containers.
    docker inspect <container_id_or_name> --format '{{json .Mounts}}'
  3. Check the same command against your main Immich server or database container to see what host paths it mounts.
  4. If the helper container's mount list is missing the host path your library and database actually live on, you've found the mismatch.

Stopping an In-Progress False Restore

  1. If you catch the restore while it's still running, stop the helper container before it finishes writing anything.
  2. Do not let the stack restart automatically until you've confirmed whether your real data on disk is intact — check the host path directly, outside of any container, to see if your files and database are still there.
  3. If the data is untouched, the fix is simply correcting the mount before re-running the migration (see below).
  4. If the restore already completed and overwrote current data with an older backup, stop the stack and restore your host data folder from your most recent known-good backup snapshot first, then correct the mount before starting anything again.

Fixing the Mount So It Doesn't Happen Again

  1. Find wherever the helper or migration container is defined — this may be in your compose file, a script that launches it via the Docker socket, or an upgrade routine bundled with Immich.
  2. Add the same volume mapping your main Immich containers use for the data path (for example, the host directory backing /volume1) so the helper sees the identical filesystem view.
  3. Make sure the mount is read/write if the migration step needs to move or reorganize files, not just read them.
  4. Re-run the migration only after confirming, with docker inspect, that the helper container's mount list now matches your main containers.
  5. Watch the logs during the migration this time — it should now see your existing database and library and proceed with the actual reorganization instead of assuming everything is missing.

This is a general fix pattern for any self-hosted app that spins up a temporary container to do maintenance work: whenever you see a new, short-lived container involved in an upgrade or migration, treat its mount list as suspect until you've verified it matches the app's regular containers.

Prevention for the Next Upgrade

  1. Back up your Immich data path and database before running any upgrade that mentions a storage or database migration in its release notes.
  2. Before upgrading, list the containers Docker will spin up as part of the process and check each one's planned mounts against your existing setup.
  3. If your Immich data lives on a NAS share with a fixed volume path (like /volume1), double-check that any auto-generated or scripted container definitions reference that exact path rather than a generic placeholder.
  4. Test upgrades on a copy of your data when the scale of your library makes that practical, so a misconfigured helper container can't touch your live photos and videos.

Frequently asked

Is this actually an Immich DNS problem?

Usually not, even though it can look like one. When a helper container triggers an unwanted restore, the containers that come back up afterward often throw connection-refused or host-not-found style errors, which reads like a DNS failure. The actual root cause is almost always a missing volume mount on a helper or migration container, not a broken Docker network or DNS resolver.

SparkBox Updates page with one-button updating
SparkBox Updates page with one-button updating

Why does Immich think its database is missing when it's clearly there?

Because a separate helper container (often a lightweight Alpine image spawned to run a storage migration like migrate_dir_to_pool) only mounted /opt and the Docker socket. It never mounted the actual data volume, for example /volume1, so from inside that helper container the database directory looks empty. The migration logic then assumes the data is missing and tries to restore from backup.

How do I check which volumes a container has mounted?

Run docker inspect against the container ID or name and look at the Mounts section of the output. Compare that list against the volume paths your main Immich server and database containers use. If the helper container is missing a path the others have, that's the mismatch causing the problem.

What if the restore already ran and overwrote my library?

Stop the stack immediately and do not let it restart automatically. Restore your host data folder from your most recent backup snapshot before bringing the containers back up, then fix the mount mismatch so it can't happen again on the next migration.

Skip auditing every container's mount list by hand

SparkBox runs Immich and its maintenance steps on a storage setup where every container — including short-lived helpers spawned during upgrades — shares the same volume definitions as the main app, so a migration step never gets a partial view of your data and decides it needs to "restore" something that was never missing.

Get SparkBox → Or read the media-server walkthrough →

Questions, or did this not match your box?

Every guide here came from a real problem someone hit. If yours behaves differently, say so — that is how these get corrected, and how the fix gets prioritised.

Ask in the community →

We answer there rather than in a comment box, because that is where the people who have already solved it are.

About this guide: Written and tested by the SparkBox team on a UGREEN DXP4800 Plus and a $7/month Hostinger VPS, both running SparkBox 1.6.670. The causes above are the real ones we've diagnosed in d/sparkbox. If something doesn't match, tell us on YouTube.