tauri-apps/tauri · error · std::io::Error

StartingBinary found current_exe() that contains a symlink…

Error message

StartingBinary found current_exe() that contains a symlink on a non-allowed platform: {}

What it means

On platforms where resolving the current executable through a symlink is considered unsafe, StartingBinary::new() resolves current_exe() and checks the resulting path for symlinks. If a symlink component is found, it returns an io::Error (InvalidData) naming the path, because the resolved binary may not be the intended Tauri app binary.

Solutions

  1. Launch the real binary instead of a symlink to it
  2. Remove or restructure the symlink so the executable path is direct
  3. If the symlink is required, check the platform-allowlist in starting_binary.rs and update Tauri or file an issue for that platform
  4. Copy (rather than link) the binary where it will be launched from

Example fix

// before
ln -s /opt/myapp/myapp ~/bin/myapp && ~/bin/myapp
// after
~/opt/myapp/myapp   # invoke the real binary directly
Defensive patterns

Strategy: validation

Validate before calling

// Resolve and check before launching
import fs from 'fs';
import path from 'path';
const exe = process.execPath; // or resolved install path
if (fs.lstatSync(exe).isSymbolicLink()) {
  console.warn('launching via symlink may fail on this platform:', fs.realpathSync(exe));
}

Try / catch

// Rust: wrap operations relying on the resolved binary in Result handling
match app.path().resolve(...) { Ok(p) => ..., Err(e) => log::error!("starting binary resolution failed: {e}") }

Prevention

When it happens

Trigger: Launching a Tauri app via a symlinked binary path on a platform not in the allowed list (e.g. running the app binary through a symlink created for version switching), then invoking functionality that resolves the starting binary.

Common situations: Package managers or wrappers that symlink the executable; Nix-style store links; developers testing the app through a symlink in ~/bin.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at crates/tauri-utils/src/platform/starting_binary.rs:31

  #[ctor(unsafe)]
  pub(super) static STARTING_BINARY: StartingBinary = unsafe { StartingBinary::new() };
}

/// Represents a binary path that was cached when the program was loaded.
pub(super) struct StartingBinary(std::io::Result<PathBuf>);

impl StartingBinary {
  /// Find the starting executable as safely as possible.
  fn new() -> Self {
    // see notes on current_exe() for security implications
    let dangerous_path = match std::env::current_exe() {
      Ok(dangerous_path) => dangerous_path,
      error @ Err(_) => return Self(error),
    };

    // note: this only checks symlinks on problematic platforms, see implementation below
    if let Some(symlink) = Self::has_symlink(&dangerous_path) {
      return Self(Err(Error::new(
        ErrorKind::InvalidData,
        format!(
          "StartingBinary found current_exe() that contains a symlink on a non-allowed platform: {}",
          symlink.display()
        ),
      )));
    }

    // we canonicalize the path to resolve any symlinks to the real exe path
    Self(dangerous_path.canonicalize())
  }

  /// A clone of the [`PathBuf`] found to be the starting path.
  ///
  /// Because [`Error`] is not clone-able, it is recreated instead.
  pub(super) fn cloned(&self) -> Result<PathBuf> {
    // false positive
    #[allow(clippy::useless_asref)]

View on GitHub (pinned to 460ec35447)