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-formatView on GitHub (pinned to 7aa98d43cf)
Solutions
- Read the appended inner error ('err') to see which step failed
- Run the process with a normal interactive-user or LocalSystem token
- Avoid launching the binary from restricted/sandboxed parents
- 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
- Do not launch RustDesk from restricted/sandboxed token contexts
- Never fall back to a permissive security descriptor when SID resolution fails — fail closed
- Test IPC listener startup as both normal user and service account in CI
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
- failed to build portable service listener security attribute
- Clipboard listener error: {}
- the staged bundle carries libdrmtap.so.0.* but --drm was not
- Invalid revision version: {args.revision_version}
- Failed to secure tcp: {}
AI-assisted analysis of rustdesk/rustdesk@7aa98d43cf (2026-08-16).
Data as JSON: /api/errors/ef520e4e02579105.
Report an issue: GitHub.