Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild
Back to Blog Troubleshooting

Immich Error Loading Image: A Storage Problem Wearing an App Costume

Sean

Platform Writer

Sep 05, 2026
8 min read

Your originals are almost certainly fine. Immich showing error loading image means the derived thumbnail is missing or cannot be delivered, and the underlying cause is nearly always one of four things: the disk filled up, a volume path changed, file ownership shifted after a restore, or a reverse proxy is refusing the request.

Immich Error Loading Image: A Storage Problem Wearing an App Costume

The reason this error is alarming is that it looks like data loss. A grid of grey tiles where your photo library used to be reads as catastrophe, particularly for people who imported from a cloud service and then deleted the source. It is worth saying clearly before anything else: the originals sit untouched in your upload location, and you can usually confirm that in thirty seconds.

Table of contents

Confirm the originals exist before troubleshooting

Do this first. It changes how the rest of the afternoon feels.

Pick an affected photo, open it, and use the download option. If the file downloads and opens correctly, the original is intact and you are looking at a thumbnail problem, not a data problem.

Then verify on disk directly:

# How much data is in the upload location
du -sh /path/to/UPLOAD_LOCATION

# The originals live under the library subdirectory
ls -R /path/to/UPLOAD_LOCATION/library | head -20

# Thumbnails are separate
du -sh /path/to/UPLOAD_LOCATION/thumbs

If library is large and thumbs is small or empty, that is the whole diagnosis: originals present, derived files missing. Everything below is about why the thumbnail generation stopped and how to restart it.

Immich keeps originals and derivatives separate precisely so this failure mode is recoverable. Thumbnails can always be regenerated from originals; the reverse is not true.

The disk is full, which is the most common cause

A photo library grows continuously and a full disk produces exactly this half-working state: uploads sometimes still squeeze through, but thumbnail generation and video transcoding fail because they need scratch space and somewhere to write output.

df -h
df -i   # inodes, which can exhaust before space on libraries with many small files

Check both. A library with hundreds of thousands of files can run out of inodes while df -h still reports free space, and the symptoms are identical.

Also check the Docker volume location specifically, which is often a different filesystem from the one you assumed. And check the Postgres data directory — Immich stores metadata and search vectors there, and a full database disk breaks things in more varied and confusing ways than a full media disk.

Clear space or grow the volume, restart the containers, then re-run thumbnail generation for missing assets. Do not skip the last step: freeing space does not retroactively generate the thumbnails that failed while it was full.

Volume paths and the double-path symptom

If the error log contains a path with a repeated segment — something like upload/upload/ followed by a UUID — that is a specific and diagnosable misconfiguration.

It means UPLOAD_LOCATION in your .env and the container’s internal mount point have been combined incorrectly, so the application is looking for files one directory deeper than they are. The files exist; the path being constructed does not.

The correct arrangement in a standard compose file is a host path mapped to the container’s /usr/src/app/upload, with UPLOAD_LOCATION naming the host side:

services:
  immich-server:
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro

The mistake is setting UPLOAD_LOCATION to a path that already ends in upload while the mount also appends it, or changing the mount point during an upgrade without updating the variable.

This surfaces most often after a migration between hosts, after moving the library to a larger disk, or after following an upgrade guide that changed the compose layout. Check the current compose file against the version for your Immich release rather than the one you set up two years ago.

Ownership and permissions after a restore

The other migration-related cause. The container runs as a specific user, and if it can read the originals but cannot write next to them, thumbnails fail while everything else appears to work.

This is what a restore from backup, a copy with the wrong flags, or a move between filesystems typically produces — the data arrives with ownership belonging to root or to whichever user performed the copy.

# What the container is complaining about
docker compose logs immich-server | grep -iE 'eacces|permission denied|enoent'

# Current ownership
ls -ln /path/to/UPLOAD_LOCATION

# Fix, matching the uid:gid the container runs as
sudo chown -R 1000:1000 /path/to/UPLOAD_LOCATION

Use the numeric uid and gid rather than names, because the user inside the container is not the same as the user on the host even when the name matches.

If you are running on a NAS, check the share’s own permission model as well — several NAS operating systems apply their own ownership over the top of what you set, and reverting a chown silently.

The reverse proxy, when originals load and thumbnails do not

If the app loads, the interface works, but images fail, the proxy in front of Immich is worth checking. Two settings cause this.

Request and response body size limits. A default nginx client_max_body_size of 1MB will refuse uploads of ordinary photographs, which produces missing assets that later present as missing thumbnails. Immich’s own guidance is to raise this substantially or disable it.

location / {
    proxy_pass http://immich:2283;
    client_max_body_size 50000M;
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    send_timeout        600s;
}

Timeouts. Large video uploads and the initial thumbnail run for a big import both take time, and a proxy that gives up after 60 seconds interrupts them midway.

A quick way to isolate this: request Immich directly on its port from inside the network, bypassing the proxy entirely. If images load there and not through the proxy, the proxy configuration is the cause and nothing inside Immich needs changing.

Regenerating thumbnails, and what to expect

Once the underlying cause is fixed, the missing derivatives have to be rebuilt. This does not happen automatically.

In the web interface, go to Administration, then Jobs, find Generate Thumbnails, and run it for Missing. Choosing All regenerates every thumbnail in the library, which on a large collection can take many hours and saturate the CPU — start with Missing and only run All if Missing does not resolve it.

Watch the job progress and the container logs together. If the job runs and fails, the log will name the reason, and it will usually be one of the four causes above rather than a new one.

Two other things worth knowing. Unsupported or unusual formats — certain RAW variants, some HEIC encoders, corrupt files from an interrupted import — can fail individually while everything else succeeds, and thumbnail format support widens over releases, so an update followed by a Missing run genuinely does fix whole categories of these.

And after any update, running the missing-assets job is a reasonable habit. Release notes flag it when a version expects one, and it is cheap compared to discovering the gap weeks later.

The wider point about self-hosting media

Every cause in this article is infrastructure rather than application: disk capacity, mount configuration, filesystem ownership, and proxy limits. The application is behaving correctly given what it was handed.

That is characteristic of self-hosted media services generally. They are storage systems with a user interface, and their failure modes are storage failure modes. The operational work is monitoring free space and inodes, keeping backups of the originals separate from the running library, and testing a restore occasionally so you find out the backup works before you need it.

It is worth being clear about what self-hosting costs. The software is free; the disk, the machine, the electricity, the upgrades, and the evening you spend on an article like this are not. For a photo library that is genuinely irreplaceable, the honest comparison is against a service where somebody else monitors the disk, and the answer depends on how you value your own time.

If you do self-host, back up the originals somewhere that is not the same disk, and not the same building. Thumbnails regenerate. Originals do not.

How this fits the rest of the stack

Error loading image is a storage or delivery problem in almost every case, and the four suspects — disk, mount path, ownership, proxy limits — cover the overwhelming majority. Fix the cause, then run the missing-thumbnails job, because clearing the cause does not backfill what failed. If any part of this setup involves a Postgres instance you would rather not be patching yourself, managed Postgres with backups and connection limits is one of the pieces RunxBuild does run, and the RunxBuild hosting calculator shows what that costs next to storage and a service.

Useful related references:

FAQ

Are my photos lost when Immich shows error loading image?

Almost certainly not. The originals live in your upload location and the error concerns the derived thumbnail or its delivery. Confirm by downloading an affected photo — if the download opens correctly, the original is intact. Then check that the library directory is large while the thumbs directory is small, which is the signature of this problem.

How do I regenerate thumbnails in Immich?

In the web interface go to Administration, then Jobs, find Generate Thumbnails, and run it for Missing. Only use All if Missing does not resolve it, because a full regeneration on a large library takes hours and saturates the CPU. Fix the underlying cause first, or the job will fail the same way.

Why did the error appear right after I updated Immich?

Thumbnail format support changes between releases, and some versions expect a missing-assets job to run afterwards as clean-up. Release notes usually flag this. Running Generate Thumbnails for Missing after an update is a cheap habit that avoids discovering the gap weeks later.

What does a repeated upload/upload path in the logs mean?

The UPLOAD_LOCATION variable and the container’s mount point are being combined incorrectly, so Immich is looking one directory deeper than the files actually are. Check your compose file against the version for your current release — this usually appears after a migration or an upgrade that changed the compose layout.

Can a reverse proxy cause Immich image errors?

Yes. A default body size limit will reject ordinary photo uploads, and a short proxy timeout interrupts large video uploads and long thumbnail runs. Test by requesting Immich directly on its port from inside the network; if images load there but not through the proxy, raise client_max_body_size and the proxy timeouts.

#immich#self hosting#docker#storage#reverse proxy