Immich "permission denied": container crash-loops or can't write uploads
· Updated 31 July 2026 · SparkBox team
Immich starts, then dies and restarts a few seconds later — or it stays up but every photo upload fails. The logs usually contain the phrase permission denied against a folder path or a database. In plain terms: the account Immich runs as isn't allowed to touch something it needs, or a credential no longer matches. The good news is that the logs almost always name the exact thing that's blocked.
Rather not hand-fix file ownership? SparkBox reads the failing container's logs first and repairs media-folder permissions and desynced credentials for you, instead of blindly restarting. See the walkthrough →
The 10-second version: Read the logs before you touch anything — docker logs immich_server. If it names a folder, fix that folder's owner on the host (chown) to match the user Immich runs as. If it says authentication failed, your database password drifted and no restart will fix it.
Step 0: read the logs first (this decides everything)
The single biggest mistake with a crash-looping container is restarting it and hoping. A restart only helps if the container was interrupted mid-startup or briefly lost a mount. It cannot fix a wrong owner on disk, a password that no longer matches, or a setting that's only read once. So look before you leap.
"Logs" here just means the text output the container prints while it runs. Get the last lines of it:
docker logs --tail 40 immich_server
If your container has a different name, list them with docker ps -a first. Now match what you see to one of the cases below. Each error message points at a different root cause, and only one fix per case will actually work.
Why this matters: a desynced credential, a config that's only read when the data volume is first created, a missing registration, and an upstream network fault all look like the same "won't come up" symptom — but a restart provably fixes none of them. The log line is what tells them apart.
Case 1: "permission denied" on a folder path (the most common)
If the log line names a path — usually something under your upload directory — Immich's internal user doesn't own that folder on the host. Immich stores originals and generated files in the location you mapped to UPLOAD_LOCATION in your compose file. If that folder on the host is owned by a different user than the one inside the container, writes fail.
Fix it
- Find the host path. In your
docker-compose.yml, look at the volume line for the Immich server — the part before the colon is the host folder (for example/mnt/photos:/usr/src/app/uploadmeans the host folder is/mnt/photos). - Find the user ID Immich runs as. If your compose sets
PUID/PGIDor auser:line, note those numbers. If it doesn't, the default is user and group1000on most setups. - Change the folder's owner to match. Replace the numbers and path with yours:
sudo chown -R 1000:1000 /mnt/photos - Restart the container so it retries the write:
docker compose restart immich_server
Don't reach for chmod 777. Making a folder world-writable does stop the error, but it also lets any process on the box modify your entire photo library. chown to the correct owner fixes the cause without opening that door.
Case 2: "authentication failed" against the database (a desynced credential)
If the log says the database rejected the login — wording like password authentication failed for user — this is a credential desync, not a file-permission problem. Immich and its PostgreSQL database each have a copy of the password. If they stop matching, Immich can't connect, and it crash-loops. Restarting does nothing because both sides simply keep disagreeing.
This is exactly the class of bug that bit several apps in SparkBox v1.6.432–437 (Immich DB auth desync among them): the app's password was changed but the database still held the old one, so the two never agreed again.
Fix it
- Open your compose file and find
DB_PASSWORDon the Immich server service andPOSTGRES_PASSWORDon the database service. They must be identical, character for character. - If they differ, make them the same value.
- Here's the catch: the database only reads
POSTGRES_PASSWORDthe first time its data volume is created. Editing the compose value afterward won't change the stored password. You either need to reset the password inside the running database, or (if you have no data to lose yet) recreate the database volume so it re-initialises with the new value. - After the two values genuinely match, bring the stack up:
docker compose up -d
Back up first. Anything involving the database volume can lose data if you delete the wrong thing. If Immich has already imported photos, resetting the password inside the running database is the safe route — don't wipe the volume.
Case 3: a setting that was only read at first init
Some values — the database password above is one, and a few storage settings are similar — are consumed once, when a data volume is first created. After that, editing the value in your compose file changes nothing, because the initialised volume already baked in the old value. If your log error stubbornly survives a correct-looking config edit, suspect this.
Fix it
- Confirm the value in your compose file is now what you want.
- Decide whether the volume holds data you need. If it's empty or disposable (a fresh install), you can recreate just that volume so it re-initialises with the corrected value.
- If it holds data, don't recreate it — change the setting from inside the service instead (as with the database password reset in Case 2).
Case 4: an upstream network or VPN fault (not a permission problem at all)
Sometimes the log shows connection refused or a timeout reaching another service, not a permission line. Immich talks to its database and its machine-learning service; if one of those isn't reachable — or a VPN container that everything routes through is down — Immich can look like it's "failing" when the real fault is next door.
Fix it
- Check the services Immich depends on are actually up:
docker psshould show the database and ML containers running, not restarting. - Read their logs too — the same
docker logs --tail 40 <name>— because the real error is often over there. - If you route traffic through a VPN or gateway container and it's unhealthy, fix that first; Immich will recover once its path back is open.
Why a restart won't help here: restarting Immich can't fix a neighbour that's down. Diagnose the dependency, not the symptom.
Frequently asked
Why does Immich say permission denied when it tries to write to the upload folder?
The user Immich runs as inside the container doesn't own the host folder mapped to UPLOAD_LOCATION. Change that folder's owner on the host (with chown) to the user ID Immich uses — commonly 1000 — then restart the container.
Will restarting the Immich container fix a permission error?
Only if it was interrupted mid-init or lost a mount. A restart can't fix a wrong owner on disk, a database password that no longer matches, or a value that's only read when the data volume is first created. Read the logs first to know which you're dealing with.
How do I read Immich container logs to find the real cause?
Run docker logs --tail 40 immich_server. Permission errors name the exact path they couldn't write. Database errors say authentication failed. Network errors mention connection refused or a timeout to another service.
Do I need to run chmod 777 to fix Immich permissions?
No. That makes the folder writable by everything on the box, which is a real security risk. Use chown to set the correct owner instead — same result, without opening your library to every process.
Skip the ownership guesswork
SparkBox diagnoses a failing Immich container from its logs before it acts — repairing media-folder permissions and desynced credentials instead of restarting into the same wall.
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.
We answer there rather than in a comment box, because that is where the people who have already solved it are.