rustdesk/rustdesk · error · std::io::Error
invalid ipc path: {path}
Error message
invalid ipc path: {path} What it means
remove_ipc_entry_via_secure_parent_fd splits the IPC path into a final entry name and a parent directory. If Path::file_name() yields nothing usable (path ends in '..', is empty, or is a bare root/relative dot path), the path cannot name a removable entry and this InvalidInput error is returned.
Source
Thrown at src/ipc/fs.rs:183
}
/// Remove one entry from the IPC parent directory through a no-follow fd on that directory.
///
/// Prefer this over `std::fs::remove_file` for anything about to be bound: `remove_file` is
/// `unlink(2)`, which returns EISDIR against a directory-typed squatter and leaves it in place,
/// and the bind that follows then fails EADDRINUSE. `remove_parent_entry_via_fd` fstats the
/// entry first and picks `AT_REMOVEDIR` when it needs to.
///
/// `AT_REMOVEDIR` is `rmdir(2)`, so the directory case this closes is the EMPTY one; a non-empty
/// squatter still yields ENOTEMPTY and still blocks the bind that follows. That is deliberate, and
/// the "obvious" fix is worse than the bug: removing it recursively would be root deleting a tree
/// an unprivileged process planted. What the caller gains there is a named error to log ahead of
/// the bind's own failure, not a successful bind.
pub(crate) fn remove_ipc_entry_via_secure_parent_fd(path: &str) -> ResultType<()> {
let entry_name = Path::new(path)
.file_name()
.and_then(|n| n.to_str())
.ok_or_else(|| Error::new(ErrorKind::InvalidInput, format!("invalid ipc path: {path}")))?
.to_owned();
let parent_dir = Path::new(path)
.parent()
.ok_or_else(|| Error::new(ErrorKind::InvalidInput, format!("invalid ipc path: {path}")))?;
let parent_c = CString::new(parent_dir.as_os_str().as_bytes().to_vec())?;
let fd = match open_ipc_parent_dir_fd(&parent_c) {
Ok(fd) => fd,
Err(open_err) => {
if open_err.kind() == ErrorKind::NotFound {
return Ok(());
}
return Err(Error::new(
open_err.kind(),
format!(
"failed to open ipc parent dir for stale socket cleanup (no-follow): path={}, parent={}, err={}",
path,
parent_dir.display(),
open_errView on GitHub (pinned to 91c9fccbb0)
Solutions
- Supply a full, absolute path ending in a concrete file name (e.g. /run/user/1000/rustdesk/drm.sock)
- Validate the configured IPC path is non-empty and has a file_name before calling
- Fix the config/env source producing the empty or malformed path
- Convert non-UTF8 paths or avoid them; this API requires UTF-8 names
Example fix
// before
remove_ipc_entry_via_secure_parent_fd(&cfg.ipc_path)?; // may be ""
// after
let path = cfg.ipc_path;
if std::path::Path::new(&path).file_name().is_none() {
anyhow::bail!("configured ipc path has no entry name: {path:?}");
}
remove_ipc_entry_via_secure_parent_fd(&path)?; Defensive patterns
Strategy: validation
Validate before calling
fn ipc_path_has_entry_name(path: &str) -> bool {
std::path::Path::new(path).file_name().map(|n| n.to_str().is_some()).unwrap_or(false)
} Try / catch
if !ipc_path_has_entry_name(&path) {
anyhow::bail!("bad ipc path {path:?}: no file name component");
}
remove_ipc_entry_via_secure_parent_fd(&path)?; Prevention
- Always configure absolute paths ending in a concrete socket file name
- Validate configured IPC paths at startup, before any listener setup
- Avoid paths derived from unexpanded templates or empty env vars
- Require UTF-8 paths (check to_str()) on Unix
When it happens
Trigger: Calling remove_ipc_entry_via_secure_parent_fd (used by new_drm_listener and remove_ipc_socket_via_secure_parent_fd) with a path like "", "/", ".", "..", or any path whose file_name component is not valid UTF-8 or is missing.
Common situations: Empty or unexpanded config/template variable for the IPC socket path; a path built from user input that collapsed to a root; non-UTF8 locale paths on Unix.
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
- failed to stat preexisting ipc parent dir entry by fd: paren
- failed to remove preexisting ipc parent dir entry by fd: par
- failed to open ipc parent dir for stale socket cleanup (no-f
- failed to mkdir ipc parent dir: postfix={}, parent={}, err={
- failed to open ipc parent dir (no-follow): postfix={}, paren
AI-assisted analysis of rustdesk/rustdesk@91c9fccbb0 (2026-09-10).
Data as JSON: /api/errors/d7296908223d3d78.
Report an issue: GitHub.