rustdesk/rustdesk · error · io::Error

failed to resolve current process SID: {}

Error message

failed to resolve current process SID: {}

What it means

On Windows, the portable-service IPC listener builds a restrictive DACL, and first resolves the current process user's SID via current_process_user_sid_string() (token → TokenUser → SID → SDDL string). This error wraps a failure anywhere in that chain, before any SDDL is constructed.

Source

Thrown at src/ipc/auth.rs:42

use std::{
    fs,
    path::{Path, PathBuf},
    sync::{Mutex, OnceLock},
};
#[cfg(windows)]
use windows::Win32::{Foundation::HANDLE, System::Pipes::GetNamedPipeClientProcessId};

#[cfg(windows)]
#[inline]
pub(crate) fn should_allow_everyone_create_on_windows(postfix: &str) -> bool {
    postfix.is_empty() || hbb_common::config::is_service_ipc_postfix(postfix)
}

#[cfg(windows)]
#[inline]
pub(crate) fn portable_service_listener_security_attributes() -> io::Result<SecurityAttributes> {
    let user_sid = crate::platform::windows::current_process_user_sid_string().map_err(|err| {
        io::Error::new(
            io::ErrorKind::Other,
            format!("failed to resolve current process SID: {}", err),
        )
    })?;
    debug_assert!(
        user_sid.starts_with("S-1-")
            && user_sid
                .bytes()
                .all(|byte| byte.is_ascii_digit() || byte == b'-'),
        "current_process_user_sid_string returned a non-SDDL SID: {}",
        user_sid
    );
    // SDDL:
    // - `D:P`                => protected DACL (no inherited ACEs)
    // - `(A;;GA;;;SY)`       => allow GENERIC_ALL to LocalSystem
    // - `(A;;GA;;;{user_sid})` => allow GENERIC_ALL to current process user SID
    // References:
    // - Security Descriptor String Format: https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format

View on GitHub (pinned to 7aa98d43cf)

Solutions

  1. Read the appended inner error ('err') to see which step failed
  2. Run the process with a normal interactive-user or LocalSystem token
  3. Avoid launching the binary from restricted/sandboxed parents
  4. If it persists, capture a token dump with whoami /all in the same context to verify the token exposes a user SID
Defensive patterns

Strategy: validation

Validate before calling

// Smoke-test SID resolution before building the listener
let sid = rustdesk::platform::windows::current_process_user_sid_string()
    .map_err(|e| log::error!("SID lookup failed: {e}"))?;
assert!(sid.starts_with("S-1-"));

Try / catch

match portable_service_listener_security_attributes() {
    Err(e) if e.to_string().contains("SID") => {
        // run in normal user context and retry; do not silently fall back to a NULL DACL
        return Err(e);
    }
    r => r,
}

Prevention

When it happens

Trigger: OpenProcessToken or GetTokenInformation failing: process token inaccessible, an impersonation/restricted token without normal user groups, or the SID-to-string conversion failing.

Common situations: Running under unusual token contexts (job objects, sandboxed restricted tokens, some service hosts); privileges stripped from the process; security software interfering with token queries.

Related errors


AI-assisted analysis of rustdesk/rustdesk@7aa98d43cf (2026-08-16). Data as JSON: /api/errors/ef520e4e02579105. Report an issue: GitHub.