spacedriveapp/spacedrive · error · anyhow::Error

Failed to start systemd service

Error message

Failed to start systemd service: {}

What it means

The final step of Linux install runs `systemctl --user start spacedrive-daemon.service`. The unit was enabled, but the start request failed: either systemd rejected the unit (bad ExecStart path, invalid data-dir) or the service started and exited immediately with a non-zero result. The CLI surfaces systemctl's stderr, which for start failures is often terse, so the real cause lives in the journal.

Solutions

  1. Get the real failure from the journal: `journalctl --user -u spacedrive-daemon -e --no-pager`.
  2. Check unit state and ExecStart resolution: `systemctl --user status spacedrive-daemon`.
  3. Ensure the data dir exists and is writable: `mkdir -p <data-dir> && touch <data-dir>/.write-test`.
  4. Stop anything holding the old daemon (`systemctl --user stop spacedrive-daemon; pkill sd-daemon`) and `systemctl --user daemon-reload` before retrying install.

Example fix

# before
sd-cli daemon install  # -> Failed to start systemd service: Job for spacedrive-daemon.service failed

# after diagnosing
journalctl --user -u spacedrive-daemon -e   # shows e.g. 'address already in use'
systemctl --user stop spacedrive-daemon && pkill -x sd-daemon
sd-cli daemon install  # -> Daemon installed and started successfully!
Defensive patterns

Strategy: try-catch

Validate before calling

# after a failed start, the journal carries the real cause
journalctl --user -u spacedrive-daemon -e --no-pager | tail -50

Try / catch

if let Err(e) = install_autostart().await {
    if e.to_string().contains("Failed to start systemd service") {
        let _ = std::process::Command::new("journalctl")
            .args(["--user", "-u", "spacedrive-daemon", "-e", "--no-pager"]).status();
    }
    return Err(e);
}

Prevention

When it happens

Trigger: sd-daemon binary moved or deleted between enable and start; the `--data-dir` directory not writable by the user; the daemon crashing at startup (port/socket already in use, invalid instance flag) so systemd reports a failed start.

Common situations: Reinstalling while an older daemon instance already owns the socket; unit file edited by hand after install without daemon-reload; data directory on a read-only or permission-restricted mount.

Related errors


AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16). Data as JSON: /api/errors/bf80cc44c2af34a8. Report an issue: GitHub.

Appendix: source

Thrown at apps/cli/src/domains/daemon/mod.rs:348

	if !output.status.success() {
		let stderr = String::from_utf8_lossy(&output.stderr);
		return Err(anyhow::anyhow!(
			"Failed to enable systemd service: {}",
			stderr
		));
	}

	// Start the service
	let output = std::process::Command::new("systemctl")
		.arg("--user")
		.arg("start")
		.arg(&service_name)
		.output()?;

	if !output.status.success() {
		let stderr = String::from_utf8_lossy(&output.stderr);
		return Err(anyhow::anyhow!(
			"Failed to start systemd service: {}",
			stderr
		));
	}

	println!("Daemon installed and started successfully!");
	println!("The daemon will start automatically on login.");
	println!();
	println!("Useful commands:");
	println!("  systemctl --user status {}", service_name);
	println!("  journalctl --user -u {} -f", service_name);

	Ok(())
}

#[cfg(target_os = "linux")]
async fn uninstall_launchd_service(instance: Option<String>) -> Result<()> {
	use std::fs;

View on GitHub (pinned to 6dfeccf211)