rustdesk/rustdesk · error · std::io::Error
failed to open ipc parent dir (no-follow): postfix={}, paren
Error message
failed to open ipc parent dir (no-follow): postfix={}, parent={}, err={} What it means
After creating (or confirming existence of) the IPC parent directory via mkdir, ensure_secure_ipc_parent_dir re-opens it with O_NOFOLLOW|O_DIRECTORY to get an fd for fchown/fchmod hardening. If this open fails, the errno is wrapped into this error. A failure here usually means the freshly-created path is not actually an openable real directory — most notably ELOOP when it is a symlink, or EACCES/EPERM.
Source
Thrown at src/ipc/fs.rs:281
let mkdir_err = std::io::Error::last_os_error();
// Handle a race where another process created the directory first.
if mkdir_err.raw_os_error() != Some(hbb_common::libc::EEXIST) {
return Err(Error::new(
mkdir_err.kind(),
format!(
"failed to mkdir ipc parent dir: postfix={}, parent={}, err={}",
postfix,
parent_dir.display(),
mkdir_err
),
)
.into());
}
}
match open_ipc_parent_dir_fd(&parent_c) {
Ok(fd) => fd,
Err(err) => {
return Err(Error::new(
err.kind(),
format!(
"failed to open ipc parent dir (no-follow): postfix={}, parent={}, err={}",
postfix,
parent_dir.display(),
err
),
)
.into());
}
}
} else {
return Err(Error::new(
open_err.kind(),
format!(
"failed to open ipc parent dir (no-follow): postfix={}, parent={}, err={}",
postfix,
parent_dir.display(),View on GitHub (pinned to 91c9fccbb0)
Solutions
- Inspect the parent path: if it is a symlink, remove it and let the code create a real directory (the O_NOFOLLOW check exists to reject exactly this).
- Verify ownership and permissions of the directory after recreation (owned by the running user, mode 0700).
- If another process races on the same path, coordinate cleanup — stop the other instance, remove stale dirs, and retry.
- Re-run after fixing environment restrictions that block opening directories with O_NOFOLLOW.
Example fix
// before: /tmp/rustdesk is a symlink planted by another user lrwxrwxrwx /tmp/rustdesk -> /home/attacker/x // after: replace with a real directory owned by the running user rm /tmp/rustdesk && mkdir -m 700 /tmp/rustdesk
Defensive patterns
Strategy: try-catch
Validate before calling
let m = std::fs::symlink_metadata("/tmp/rustdesk");
if let Ok(m) = m {
if m.file_type().is_symlink() {
eprintln!("/tmp/rustdesk is a symlink; remove it before starting");
}
} Type guard
fn is_real_dir(path: &str) -> bool {
std::fs::symlink_metadata(path)
.map(|m| m.is_dir() && !m.file_type().is_symlink())
.unwrap_or(false)
} Try / catch
match new_drm_listener(&path) {
Err(e) if e.to_string().contains("failed to open ipc parent dir") => {
// likely symlink or permission issue; recreate the dir
let _ = std::fs::remove_dir_all(parent_if_symlink(&path));
new_drm_listener(&path)
}
other => other,
} Prevention
- Remove stale IPC directories on uninstall/upgrade instead of leaving them
- Monitor for symlinked IPC paths on shared/multi-user machines
- Create IPC dirs with mode 0700 owned by the service user
- Stop competing instances before cleanup so nothing replaces the dir mid-run
When it happens
Trigger: new_listener or new_drm_listener when open_ipc_parent_dir_fd fails after a successful/raced mkdir: the created 'directory' is a symlink planted between mkdir and open, permissions changed so the user cannot open it, or another component in the path is not a directory.
Common situations: A malicious or misconfigured pre-existing symlink at the IPC directory location (TOCTOU hardening doing its job); an attacker or leftover state replaced the dir; restricted environments where O_NOFOLLOW directory opens are denied.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- failed to open ipc parent dir for stale socket cleanup (no-f
- failed to stat preexisting ipc parent dir entry by fd: paren
- failed to remove preexisting ipc parent dir entry by fd: par
- invalid ipc path: {path}
- failed to mkdir ipc parent dir: postfix={}, parent={}, err={
AI-assisted analysis of rustdesk/rustdesk@91c9fccbb0 (2026-09-10).
Data as JSON: /api/errors/6b98cebcb9be1075.
Report an issue: GitHub.