rustdesk/rustdesk · error · io::Error
failed to build portable service listener security attribute
Error message
failed to build portable service listener security attributes from SDDL '{}': {} What it means
The DACL SDDL string 'D:P(A;;GA;;;SY)(A;;GA;;;<user_sid>)' (protected DACL; GENERIC_ALL for LocalSystem and the current user) is converted into SECURITY_ATTRIBUTES via SecurityAttributes::from_sddl. This error means that conversion failed, and includes both the SDDL and the underlying error.
Source
Thrown at src/ipc/auth.rs:64
})?;
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
// - ACE strings in SDDL: https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings
let sddl = format!("D:P(A;;GA;;;SY)(A;;GA;;;{user_sid})");
SecurityAttributes::from_sddl(&sddl).map_err(|err| {
io::Error::new(
io::ErrorKind::Other,
format!(
"failed to build portable service listener security attributes from SDDL '{}': {}",
sddl, err
),
)
})
}
#[cfg(target_os = "macos")]
#[inline]
fn macos_service_ipc_allows_gui_and_service_binaries(
peer_exe: &Path,
current_exe: &Path,
postfix: &str,
) -> bool {
if postfix != crate::POSTFIX_SERVICE {
return false;View on GitHub (pinned to 7aa98d43cf)
Solutions
- Copy the SDDL from the message and validate it with PowerShell: New-Object System.Security.AccessControl.RawSecurityDescriptor('<sddl>')
- Check the appended inner error for the exact Win32 failure
- Verify the account's SID is well-formed: whoami /user
- If the SID string is malformed, fix current_process_user_sid_string rather than the SDDL template
Defensive patterns
Strategy: validation
Validate before calling
# Validate the exact SDDL before shipping changes to it (PowerShell) New-Object System.Security.AccessControl.RawSecurityDescriptor ` 'D:P(A;;GA;;;SY)(A;;GA;;;S-1-5-21-1004336348-1177238915-682003330-512)'
Try / catch
if let Err(e) = SecurityAttributes::from_sddl(&sddl) {
log::error!("SDDL rejected: '{sddl}': {e}");
return Err(e); // fail closed — no permissive fallback
} Prevention
- Keep the debug_assert guard that verifies the SID is plain SDDL (S-1-digits-dashes)
- Never weaken the DACL on failure — the listener must not start with a NULL security attribute
- Re-test whenever the SID source (current_process_user_sid_string) changes
When it happens
Trigger: The SID string embedded in the SDDL is malformed (non-SDDL characters — the debug_assert above checks 'S-1-...' digits/dashes), or ConvertStringSecurityDescriptorToSecurityDescriptor failed from memory/parameter errors.
Common situations: current_process_user_sid_string returning an unexpected format (logon SIDs or placeholder output); downlevel Windows rejecting the SDDL flags; corrupted user account SID.
Related errors
- failed to resolve current process SID: {}
- 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/b8d08629c362719a.
Report an issue: GitHub.