immich-app/immich · error · IOException

Could not read image data for $assetId

Error message

Could not read image data for $assetId

What it means

getEncodedImageInternal in LocalImagesImpl.kt opens a MediaStore content InputStream for the given asset ID and reads all bytes. If openInputStream returns null (the provider cannot open the URI) it throws IOException 'Could not read image data for $assetId', which propagates to the Flutter side as a load failure for that thumbnail.

Solutions

  1. Re-query MediaStore for the asset ID; treat this asset as stale and remove it from the local listing.
  2. Verify storage/photo permissions (READ_MEDIA_IMAGES / READ_EXTERNAL_STORAGE) are granted.
  3. Check the file is not a cloud-only placeholder — trigger download or skip until available.
  4. Re-run a full media sync so deleted assets are pruned before requesting thumbnails.

Example fix

// before
final bytes = await LocalImagesApi.getEncodedImage(assetId);
// after
try {
  bytes = await LocalImagesApi.getEncodedImage(assetId);
} catch (e) {
  await removeFromLocalIndex(assetId); // stale MediaStore entry
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Dart: confirm asset still exists locally before requesting bytes
final exists = await localApi.assetExists(assetId); // re-query MediaStore

Try / catch

try {
  bytes = await api.getEncodedImage(assetId);
} catch (e) {
  markAssetMissing(assetId); // prune stale entry, continue sync
}

Prevention

When it happens

Trigger: The asset ID no longer exists in MediaStore (deleted or moved), the URI is unresolvable, or the content provider denies the stream for a cloud-backed/offline item.

Common situations: Thumbnailing assets that were deleted on the device since the last sync; backups restored to a device where local files are cloud placeholders; missing READ_MEDIA_IMAGES permission on newer Android versions.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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

Appendix: source

Thrown at mobile/android/app/src/main/kotlin/app/alextran/immich/images/LocalImagesImpl.kt:190

          request.callback(CANCELLED)
        } catch (_: Exception) {
        }
      }
    }
  }

  private fun getEncodedImageInternal(
    assetId: String,
    callback: (Result<Map<String, Long>?>) -> Unit,
    signal: CancellationSignal
  ) {
    signal.throwIfCanceled()
    val id = assetId.toLong()
    val uri = ContentUris.withAppendedId(Images.Media.EXTERNAL_CONTENT_URI, id)

    signal.throwIfCanceled()
    val bytes = resolver.openInputStream(uri)?.use { it.readBytes() }
      ?: throw IOException("Could not read image data for $assetId")

    signal.throwIfCanceled()
    val pointer = NativeBuffer.allocate(bytes.size)
    try {
      val buffer = NativeBuffer.wrap(pointer, bytes.size)
      buffer.put(bytes)
      signal.throwIfCanceled()
      callback(Result.success(mapOf(
        "pointer" to pointer,
        "length" to bytes.size.toLong()
      )))
    } catch (e: Exception) {
      NativeBuffer.free(pointer)
      throw e
    }
  }

  private fun getThumbnailBufferInternal(

View on GitHub (pinned to e55ac299a4)