rustdesk/rustdesk · error
Portable service shared-memory ACL file target is a reparse
Error message
Portable service shared-memory ACL file target is a reparse point and is rejected: '{}' What it means
Raised by set_path_permission_for_portable_service_shmem_impl (file variant) when the file target carries the reparse-point attribute. Symlinked or placeholder file targets are rejected because applying a protected DACL would hit the reparse target or the link inconsistently, which is a security hazard for shared memory.
Source
Thrown at src/platform/windows/acl.rs:389
fn set_path_permission_for_portable_service_shmem_impl(
path: &Path,
expect_dir: bool,
) -> ResultType<()> {
if expect_dir {
validate_portable_service_shmem_dir_target(path)?;
} else {
let metadata_result = fs::symlink_metadata(path);
match metadata_result {
Ok(metadata) => {
if metadata.file_type().is_dir() {
bail!(
"Portable service shared-memory ACL target is a directory, expected file-like path: '{}'",
path.display()
);
}
if is_reparse_point(&metadata) {
bail!(
"Portable service shared-memory ACL file target is a reparse point and is rejected: '{}'",
path.display()
);
}
}
Err(e)
if e.kind() == io::ErrorKind::NotFound
|| e.kind() == io::ErrorKind::PermissionDenied =>
{
// Keep going and let Win32 ACL APIs return the final OS error.
// `Path::exists()/is_file()` and metadata can collapse ACL-denied paths into
// a false "not found" signal under restricted directory ACLs.
}
Err(e) => {
bail!(
"Failed to inspect portable service shared-memory ACL target '{}': {}",
path.display(),
eView on GitHub (pinned to 91c9fccbb0)
Solutions
- Use the real (non-link) file path; resolve the symlink before applying the ACL.
- Move the file out of the synced/placeholder location into a plain NTFS directory.
- If a test needs a reparse target, update the test to use a real file, matching the function's contract.
Example fix
// before set_path_permission_for_portable_service_shmem_file(&link_path)?; // after let real = fs::read_link(&link_path)?; set_path_permission_for_portable_service_shmem_file(&real)?;
Defensive patterns
Strategy: validation
Validate before calling
let m = std::fs::symlink_metadata(&file_path)?;
if m.is_dir() || m.is_symlink() {
return Err(anyhow!("reparse/dir target rejected: {}", file_path.display()));
} Type guard
fn is_plain_file(p: &Path) -> bool {
matches!(std::fs::symlink_metadata(p), Ok(m) if !m.is_dir() && !m.is_symlink())
} Try / catch
if let Err(e) = set_path_permission_for_portable_service_shmem_file(&p) {
if e.to_string().contains("reparse point") {
let real = std::fs::read_link(&p).unwrap_or(p.to_path_buf());
set_path_permission_for_portable_service_shmem_file(&real)?;
} else { return Err(e); }
} Prevention
- Do not symlink shmem files in production deployments
- Keep shmem files out of cloud-synced/placeholder directories
- Resolve links with fs::read_link before ACL operations
When it happens
Trigger: Calling set_path_permission_for_portable_service_shmem_file(path) where symlink_metadata shows path is a symlink, or where the file is a OneDrive/Dev Drive placeholder with FILE_ATTRIBUTE_REPARSE_POINT.
Common situations: The shmem file path is a symlink created for testing (fs::symlink_file); the file lives in a cloud-synced folder that placeholders its contents; a junctioned directory redirects to the file.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Portable service shared-memory ACL directory target is a rep
- ACL target directory is a reparse point and is rejected: '{}
- custom.txt at {:?} is a symlink, refusing to stage for secur
- failed to resolve current process SID: {}
- failed to build portable service listener security attribute
AI-assisted analysis of rustdesk/rustdesk@91c9fccbb0 (2026-09-10).
Data as JSON: /api/errors/102b2352f1682bd8.
Report an issue: GitHub.