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
- Launch the real binary instead of a symlink to it
- Remove or restructure the symlink so the executable path is direct
- If the symlink is required, check the platform-allowlist in starting_binary.rs and update Tauri or file an issue for that platform
- 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
- Install binaries as real files, not symlinks, on non-allowed platforms
- Test app launches from the actual install location in packaging CI
- Document for users not to symlink the executable
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
- asset protocol not configured to allow the path
- asset protocol path " " is not valid
- asset protocol path " " is not valid
- Can't read source directory
- Could not read binary file.
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)