tauri-apps/tauri · error

failed to read icon

Error message

failed to read icon {}: {}

What it means

EmbeddedImage::new_png decodes a PNG icon during macro expansion. png::Decoder::read_info() failing (invalid PNG signature, corrupt chunks, unsupported format) triggers this panic with the icon path and decoder error, aborting the build.

Solutions

  1. Verify the file is a real PNG (`file icon.png` should report PNG image data)
  2. Re-export or re-encode the image as PNG (e.g. `magick input.webp output.png`)
  3. Re-download or restore the icon from version control
  4. Open the PNG in an editor and re-save it

Example fix

// before
cp photo.jpg icon.png
// after
magick photo.jpg -resize 32x32 icon.png
Defensive patterns

Strategy: validation

Validate before calling

import imghdr, sys
if imghdr.what('icon.png') != 'png':
    sys.exit('icon.png is not a real PNG')
# or: from PIL import Image; Image.open('icon.png').verify()

Prevention

When it happens

Trigger: A .png passed to the icon/embedded-image path that is not a valid PNG (wrong magic bytes, truncated file, interlaced variant the decoder rejects).

Common situations: Renamed JPEG/GIF/WebP files with a .png extension; truncated PNGs from failed downloads or interrupted transfers; corrupt assets after a bad git checkout.

Related errors


AI-assisted analysis of tauri-apps/tauri@460ec35447 (2026-09-18). Data as JSON: /api/errors/d47c02b9943c0cb2. Report an issue: GitHub.

Appendix: source

Thrown at crates/tauri-codegen/src/image.rs:80

      .to_vec();

    Cached::try_from(rgba).map(|cache| Self {
      cache,
      root: root.clone(),
      format: IconFormat::Image {
        width: entry.width(),
        height: entry.height(),
      },
    })
  }

  /// Cache a PNG icon as RGBA data, see [`ImageFormat::Image`].
  pub fn new_png(root: &TokenStream, icon: &Path) -> EmbeddedAssetsResult<Self> {
    let buf = Self::open(icon);
    let decoder = png::Decoder::new(Cursor::new(&buf));
    let mut reader = decoder
      .read_info()
      .unwrap_or_else(|e| panic!("failed to read icon {}: {}", icon.display(), e));

    if reader.output_color_type().0 != png::ColorType::Rgba {
      panic!("icon {} is not RGBA", icon.display());
    }

    let mut rgba = Vec::with_capacity(reader.output_buffer_size().unwrap());
    while let Ok(Some(row)) = reader.next_row() {
      rgba.extend(row.data());
    }

    Cached::try_from(rgba).map(|cache| Self {
      cache,
      root: root.clone(),
      format: IconFormat::Image {
        width: reader.info().width,
        height: reader.info().height,
      },
    })

View on GitHub (pinned to 460ec35447)