immich-app/immich · warning

Thumbnail generation failed for asset

Error message

Thumbnail generation failed for asset ${id}: not found in database or missing metadata

What it means

The AssetEditThumbnailGeneration job handler loads the asset with the metadata required for thumbnail generation; when no row is found (or required relations/metadata are absent) it logs this warning and returns JobStatus.Failed. This prevents generating thumbnails for assets that were deleted or lack the needed data.

Solutions

  1. Check the asset exists with its edited files in the database; if deleted, ignore the failed job
  2. Re-trigger thumbnail generation from the admin jobs UI after confirming the asset exists
  3. Flush stale editor-queue jobs if they reference purged assets
  4. If metadata is missing, re-run metadata extraction before the thumbnail job

Example fix

// before
if (!asset) { this.logger.warn(`Thumbnail generation failed for asset ${id}: not found in database or missing metadata`); return JobStatus.Failed; }
// after
if (!asset) { this.logger.warn(`Thumbnail generation failed for asset ${id}: not found in database or missing metadata`); return JobStatus.Failed; }
// remediation: re-run metadata extraction, then retry thumbnail generation
Defensive patterns

Strategy: validation

Validate before calling

const asset = await assetJobRepository.getForGenerateThumbnailJob(id);
if (!asset) return JobStatus.Failed; // skip; asset gone or metadata missing

Try / catch

const asset = await this.assetJobRepository.getForGenerateThumbnailJob(id);
if (!asset) { this.logger.warn(`Thumbnail generation failed for asset ${id}`); return JobStatus.Failed; }

Prevention

When it happens

Trigger: An edit-thumbnail job is processed for an asset id that no longer exists, or getForGenerateThumbnailJob returns null because required joins (files/paths/exif) are missing for the edited asset.

Common situations: Asset deleted while an editor job was queued; editor queue replaying stale jobs after DB cleanup; job enqueued before the edited file was committed to the database.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at server/src/services/media.service.ts:160

    if (!asset) {
      return JobStatus.Failed;
    }

    await this.storageCore.moveAssetImage(asset, AssetFileType.FullSize, image.fullsize.format);
    await this.storageCore.moveAssetImage(asset, AssetFileType.Preview, image.preview.format);
    await this.storageCore.moveAssetImage(asset, AssetFileType.Thumbnail, image.thumbnail.format);
    await this.storageCore.moveAssetVideo(asset);

    return JobStatus.Success;
  }

  @OnJob({ name: JobName.AssetEditThumbnailGeneration, queue: QueueName.Editor })
  async handleAssetEditThumbnailGeneration({ id }: JobOf<JobName.AssetEditThumbnailGeneration>): Promise<JobStatus> {
    const asset = await this.assetJobRepository.getForGenerateThumbnailJob(id);
    const config = await this.getConfig({ withCache: true });

    if (!asset) {
      this.logger.warn(`Thumbnail generation failed for asset ${id}: not found in database or missing metadata`);
      return JobStatus.Failed;
    }

    const generated = await this.generateEditedThumbnails(asset, config);
    await this.syncFiles(
      asset.files.filter((file) => file.isEdited),
      generated?.files ?? [],
    );

    let thumbhash: Buffer | undefined = generated?.thumbhash;
    if (!thumbhash) {
      const extractedImage = await this.extractOriginalImage(asset, config.image);
      const { info, data, colorspace } = extractedImage;

      thumbhash = await this.mediaRepository.generateThumbhash(data, {
        colorspace,
        processInvalidImages: false,
        raw: info,

View on GitHub (pinned to e55ac299a4)