immich-app/immich · error · NotFoundException

Asset media not found

Error message

Asset media not found

What it means

viewThumbnail resolved the requested rendition size (with fallback from fullsize to preview when fullsize is unavailable) but the resulting file path is empty — i.e. no stored rendition file exists for this asset at any acceptable size. It throws NotFoundException('Asset media not found').

Solutions

  1. Wait for background thumbnail generation to finish, then retry.
  2. Check the Jobs status in the admin UI; re-run the 'Generate Thumbnails' job for missing assets.
  3. Verify the storage volume is mounted and the preview paths under the data directory exist.
  4. Confirm the asset id is correct — a wrong id pointing to a media-less record yields the same 404.

Example fix

// before
const thumb = await getThumb(id); // 404 right after upload
// after
let thumb = null;
for (let i = 0; i < 10 && !thumb; i++) {
  thumb = await getThumb(id).catch(() => null);
  if (!thumb) await sleep(2000); // wait for thumbnail job
}
Defensive patterns

Strategy: fallback

Try / catch

try { return await getThumbnail(id, size); } catch (e) { if (e.status === 404) return placeholderImage(); throw e; }

Prevention

When it happens

Trigger: GET /api/assets/:id/thumbnail for an asset whose preview image has not been generated yet (upload still processing, thumbnail generation job failed/disabled) and fullsize is also absent.

Common situations: Requesting thumbnails immediately after upload before the thumbnail job runs; storage-template or library migration left files missing; transcoding/thumbnail worker crashed; asset exists in DB but its files were removed from disk.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15). Data as JSON: /api/errors/1cfd13b823a4af21. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/asset-media.service.ts:285

    const { originalPath, originalFileName, path } = await this.assetRepository.getForThumbnail(
      id,
      size,
      dto.edited ?? false,
    );

    if (size === AssetFileType.FullSize && mimeTypes.isWebSupportedImage(originalPath) && !dto.edited) {
      // use original file for web supported images
      return { targetSize: 'original' };
    }

    if (dto.size === AssetMediaSize.FULLSIZE && !path) {
      // downgrade to preview if fullsize is not available.
      // e.g. disabled or not yet (re)generated
      return { targetSize: AssetMediaSize.PREVIEW };
    }

    if (!path) {
      throw new NotFoundException('Asset media not found');
    }

    const fileNameBase =
      auth.sharedLink && !auth.sharedLink.showExif ? id : getFileNameWithoutExtension(originalFileName);
    const fileName = `${fileNameBase}_${size}${getFilenameExtension(path)}`;

    return new ImmichFileResponse({
      fileName,
      path,
      contentType: mimeTypes.lookup(path),
      cacheControl: CacheControl.PrivateWithCache,
    });
  }

  async playbackVideo(auth: AuthDto, id: string): Promise<ImmichFileResponse> {
    await this.requireAccess({ auth, permission: Permission.AssetView, ids: [id] });

    const asset = await this.assetRepository.getForVideo(id);

View on GitHub (pinned to e55ac299a4)