rustdesk/rustdesk · error

[root-update] mktemp output error: {}

Error message

[root-update] mktemp output error: {}

What it means

This error is raised in `update_from_dmg_as_root` (src/platform/macos.rs:1096) when the stdout of `/usr/bin/mktemp -d /tmp/.rustdeskupdate-root-XXXXXX` is not valid UTF-8. It is a wrapper around `String::from_utf8` failure, meaning the temp-directory path returned by mktemp contained invalid bytes — practically a system-level anomaly since mktemp emits plain ASCII paths.

Source

Thrown at src/platform/macos.rs:1096

}

/// Performs a silent update from a DMG file without any osascript dialog.
/// Must be called from a process running as root (e.g. the service binary).
pub fn update_from_dmg_as_root(dmg_path: &str, expected_version: &str) -> ResultType<()> {
    let app_name = crate::get_app_name();
    if app_name.is_empty()
        || !app_name
            .bytes()
            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'.' | b'_' | b'-'))
    {
        bail!("[root-update] unsafe application name");
    }
    let app_bundle = format!("/Applications/{}.app", app_name);
    let tmp_dir_output = std::process::Command::new("/usr/bin/mktemp")
        .args(&["-d", "/tmp/.rustdeskupdate-root-XXXXXX"])
        .output()?;
    let tmp_dir = String::from_utf8(tmp_dir_output.stdout)
        .map_err(|e| anyhow!("[root-update] mktemp output error: {}", e))?
        .trim()
        .to_string();
    if tmp_dir.is_empty() {
        bail!("[root-update] Failed to create temp directory");
    }
    {
        use std::os::unix::fs::PermissionsExt;
        std::fs::set_permissions(&tmp_dir, std::fs::Permissions::from_mode(0o700))?;
    }
    let agent_plist = format!("/Library/LaunchAgents/com.carriez.{}_server.plist", app_name);
    let daemon_plist = format!("/Library/LaunchDaemons/com.carriez.{}_service.plist", app_name);

    log::info!("[root-update] Starting silent root update from {}", dmg_path);
    // Check sessions before extracting to avoid unnecessary work
    if !crate::updater::has_no_active_conns_ipc() {
        bail!("[root-update] Active session detected, deferring update.");
    }
    // Extract DMG to temp dir

View on GitHub (pinned to 91c9fccbb0)

Solutions

  1. Verify `/usr/bin/mktemp` is the genuine system binary (`which -a mktemp`, check for wrappers/aliases) and restore it if replaced.
  2. Check that `/tmp` resolves to a plain ASCII path (`ls -ld /tmp`) and remove symlinks or mount points with non-UTF-8 names.
  3. Confirm the filesystem hosting /tmp is HFS+/APFS, not a network or unusual filesystem that mangles names.
  4. Retry the update after fixing the environment; if transient, re-running the update is safe because nothing has been staged yet.

Example fix

// before: diagnostic
$ ls -ld /tmp
lrwxr-xr-x 1 root wheel 33 /tmp -> /private/tép
// after: fix the link
$ sudo ln -sfn /private/tmp /tmp
Defensive patterns

Strategy: try-catch

Validate before calling

let out = std::process::Command::new("/usr/bin/mktemp").args(&["-d", "/tmp/.t-XXXXXX"]).output().ok()?;
if out.status.success() && String::from_utf8(out.stdout).is_ok() && !out.stdout.is_empty() { Some(()) } else { None }

Try / catch

match update_from_dmg_as_root(dmg, version) {
    Err(e) if e.to_string().contains("mktemp output error") => {
        log::error!("mktemp emitted non-UTF-8 path; inspect /tmp and /usr/bin/mktemp: {}", e);
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `update_from_dmg_as_root` on a system where `/tmp` resolves to a path containing non-UTF-8 bytes (e.g. TMPDIR pointing to a directory with non-UTF-8 characters, or a modified mktemp wrapper producing binary output). Note `Command::new("/usr/bin/mktemp")` ignores TMPDIR, so this usually implies a replaced/aliased binary or filesystem-level oddity.

Common situations: Systems with unusual locale/filesystem setups where /tmp is a symlink chain into non-UTF-8-named directories; security tooling or wrappers that intercept mktemp and emit extra non-text output; corrupted system files.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of rustdesk/rustdesk@91c9fccbb0 (2026-09-10). Data as JSON: /api/errors/37a319e8bf0048fd. Report an issue: GitHub.