rustdesk/rustdesk · warning
[root-update] Active session started during download, deferr
Error message
[root-update] Active session started during download, deferring update.
What it means
Because the download as root can take minutes, `check_update_as_root` rechecks for active remote sessions via `has_no_active_conns_ipc()` right before installing. If a session has started during the download, the temp directory is cleaned up and this bail aborts the install so a user is not disconnected mid-session. This is an expected, intentional deferral rather than a fault.
Source
Thrown at src/updater.rs:647
bail!("[root-update] Failed to download: {}", response.status());
}
// Create file exclusively (O_EXCL) and stream response directly into it
{
let mut file = std::fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(&file_path)
.map_err(|e| { let _ = std::fs::remove_dir_all(&private_tmp); e })?;
std::io::copy(&mut response, &mut file)
.map_err(|e| { let _ = std::fs::remove_dir_all(&private_tmp); e })?;
}
log::info!("[root-update] Downloaded to {}", tmp_path);
// Recheck active sessions before installing — download can take minutes
if !has_no_active_conns_ipc() {
if let Err(e) = std::fs::remove_dir_all(&private_tmp) {
log::warn!("[root-update] Failed to remove temp dir {}: {}", private_tmp, e);
}
bail!("[root-update] Active session started during download, deferring update.");
}
// Install silently as root
let result = crate::platform::update_from_dmg_as_root(&tmp_path, &version);
// Clean up download directory
if let Err(e) = std::fs::remove_dir_all(&private_tmp) {
log::warn!("[root-update] Failed to remove temp dir {}: {}", private_tmp, e);
}
result.map(|_| true)
}
#[cfg(test)]
mod tests {
use super::get_download_file_from_url;
#[test]
fn update_download_file_accepts_expected_github_asset_urls() {
let file = get_download_file_from_url(
"https://github.com/rustdesk/rustdesk/releases/download/1.4.0/rustdesk-1.4.0-x86_64.dmg",View on GitHub (pinned to 91c9fccbb0)
Solutions
- No action needed — the update is deferred and will be retried on a later updater run.
- Ensure the machine is idle (no active RustDesk sessions) when an immediate update is required.
- Retry after all sessions have ended.
Defensive patterns
Strategy: fallback
Try / catch
// treat as benign deferral, not failure
if let Err(e) = check_update_as_root() {
if e.to_string().contains("deferring update") {
log::info!("update postponed until sessions end");
return Ok(()); // expected path
}
} Prevention
- Schedule updates for idle windows on unattended machines.
- Treat this message as expected behavior; do not alert on it.
- Verify no active sessions exist before manually forcing an update.
When it happens
Trigger: An incoming remote connection/session starts between the initial check and the end of the dmg download, so `has_no_active_conns_ipc()` returns false at install time.
Common situations: Long downloads on slow networks overlapping with a legitimate user connecting to the machine; scheduled updates racing with working hours; unattended machines that suddenly receive connections.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- [root-update] Active session detected after extraction, defe
- [root-update] active session started before update launch
- cursor changed
- [root-update] GUI session set changed before update launch
- [root-update] URL failed allowlist check: {}
AI-assisted analysis of rustdesk/rustdesk@91c9fccbb0 (2026-09-10).
Data as JSON: /api/errors/6d6219a0d6ce380c.
Report an issue: GitHub.