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
- Verify the file is a real PNG (`file icon.png` should report PNG image data)
- Re-export or re-encode the image as PNG (e.g. `magick input.webp output.png`)
- Re-download or restore the icon from version control
- 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
- Never rename other formats to .png; always transcode
- Verify downloads with checksums
- Run `magick identify` on icons in CI
- Re-save suspect icons in an editor before committing
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)