tauri-apps/tauri · error

couldn't find a square icon to use as AppImage icon

Error message

couldn't find a square icon to use as AppImage icon

What it means

When building a Linux AppImage, tauri-bundler's linuxdeploy step selects the largest square icon from the provided icon list via `max_by_key` on width among icons where width == height, and expects at least one such icon. An empty or all-non-square icon set makes max_by_key return None and the expect panics. The library requires at least one square icon to register AppImage icons.

Solutions

  1. Add a square PNG icon to `bundle.icon` in tauri.conf.json (e.g. `icons/128x128.png` or `icons/icon.png`).
  2. Run `tauri icon path/to/app-icon.png` to generate the full standard square icon set.
  3. Check that listed icon files actually exist and are valid PNG/ICO files, not 404s or misnamed paths.
  4. If using a rectangular logo, pad it to a square before adding it to the icon list.

Example fix

// before
"icon": ["icons/banner.png"] // 128x64
// after
"icon": ["icons/32x32.png", "icons/128x128.png", "icons/icon.png"]
Defensive patterns

Strategy: validation

Validate before calling

let icons = tauri_utils::config::read_icons(&config)?;
if !icons.iter().any(|i| i.width == i.height) {
  panic!("bundle.icon must include at least one square PNG (e.g. icons/128x128.png) for AppImage");
}

Prevention

When it happens

Trigger: Running an AppImage bundle (`tauri build` on Linux targeting appimage) with `bundle.icon` entries containing no square image — all icons rectangular, the list empty, or icon files that failed to load earlier so the filtered set is empty.

Common situations: tauri.conf.json icons defaulting to or listing only rectangular PNGs (e.g. 128x64 banners); forgetting to generate the required `32x32.png`/`128x128.png`/`icon.png` square icons; icons in an unsupported format silently excluded.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at crates/tauri-bundler/src/bundle/linux/appimage/linuxdeploy.rs:101

    .with_context(|| "Failed to copy custom files")?;

  fs::create_dir_all(&output_path)?;
  let app_dir_path = output_path.join(format!("{}.AppDir", settings.product_name()));
  let appimage_filename = format!(
    "{}_{}_{}.AppImage",
    settings.product_name(),
    settings.version_string(),
    appimage_arch
  );
  let appimage_path = output_path.join(&appimage_filename);
  fs_utils::create_dir(&app_dir_path, true)?;

  fs::create_dir_all(&tools_path)?;
  let larger_icon = icons
    .iter()
    .filter(|i| i.width == i.height)
    .max_by_key(|i| i.width)
    .expect("couldn't find a square icon to use as AppImage icon");
  let larger_icon_path = larger_icon
    .path
    .strip_prefix(package_dir.join("data"))
    .unwrap()
    .to_string_lossy()
    .to_string();

  log::info!(action = "Bundling"; "{} ({})", appimage_filename, appimage_path.display());

  let app_dir_usr = app_dir_path.join("usr/");
  let app_dir_usr_bin = app_dir_usr.join("bin/");
  let app_dir_usr_lib = app_dir_usr.join("lib/");

  fs_utils::copy_dir(&data_dir.join("usr/"), &app_dir_usr)?;

  // Using create_dir_all for a single dir so we don't get errors if the path already exists
  fs::create_dir_all(&app_dir_usr_bin)?;
  fs::create_dir_all(app_dir_usr_lib)?;

View on GitHub (pinned to 460ec35447)