tauri-apps/tauri · error

icon is not RGBA

Error message

icon {} is not RGBA

What it means

new_png requires the PNG's output color type to be RGBA before embedding. If the decoded PNG uses another color type (RGB, grayscale, palette, etc.) the macro panics with `icon {path} is not RGBA`, because the embedded image is expected to carry premultiplied-free RGBA bytes.

Solutions

  1. Convert the PNG to 32-bit RGBA (e.g. `magick icon.png -define png:color-type=6 icon.png`)
  2. Re-export from the design tool with transparency/alpha enabled
  3. Use `pngcrush`/`oxipng` options that keep RGBA
  4. If no alpha is needed, pre-composite onto a background and save as RGBA

Example fix

// before
magick icon.png -strip icon.png  // may output RGB
// after
magick icon.png PNG32:icon.png  // forces 32-bit RGBA
Defensive patterns

Strategy: validation

Validate before calling

from PIL import Image
im = Image.open('icon.png')
if im.mode not in ('RGBA', 'LA'):
    Image.open('icon.png').convert('RGBA').save('icon.png')

Prevention

When it happens

Trigger: Embedding a PNG saved without an alpha channel (e.g. RGB 24-bit, grayscale, or indexed/palette PNG) through the icon macro path.

Common situations: Exporting icons from Photoshop/Figma without alpha; optimizing icons with tools that strip the alpha channel; downloading logos that are opaque RGB PNGs.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

      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,
      },
    })
  }

  fn open(path: &Path) -> Vec<u8> {

View on GitHub (pinned to 460ec35447)