spacedriveapp/spacedrive · critical

DATA_DIR must be set in production

Error message

DATA_DIR must be set in production

What it means

The sd-server binary resolves its data directory from the --data-dir flag, then the DATA_DIR env var. In release builds (not(debug_assertions)) the expect panics when neither is provided; debug builds fall back to ~/.spacedrive so dev workflows share data with the desktop app. This is an intentional fail-fast so a production server never silently writes state to an unpredictable working directory.

Source

Thrown at apps/server/src/main.rs:403

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
	// Initialize logging
	tracing_subscriber::fmt()
		.with_env_filter(
			tracing_subscriber::EnvFilter::try_from_default_env()
				.unwrap_or_else(|_| "info,sd_core=debug,sd_server=debug".into()),
		)
		.init();

	let args = Args::parse();

	// Resolve data directory
	let base_data_dir = args.data_dir.unwrap_or_else(|| {
		#[cfg(not(debug_assertions))]
		{
			std::env::var("DATA_DIR")
				.expect("DATA_DIR must be set in production")
				.into()
		}
		#[cfg(debug_assertions)]
		{
			// Default to `~/.spacedrive` in dev — matches the Tauri desktop app,
			// so `just dev-server` and `just dev-desktop` share libraries and
			// data persists between runs. Falls back to a tempdir only if the
			// home directory can't be resolved.
			std::env::var("DATA_DIR")
				.map(PathBuf::from)
				.or_else(|_| {
					dirs::home_dir()
						.map(|h| h.join(".spacedrive"))
						.ok_or(())
				})
				.unwrap_or_else(|_| {
					warn!("Could not resolve home directory; falling back to tempdir");
					let temp = tempfile::tempdir().expect("Failed to create temp dir");

View on GitHub (pinned to 6dfeccf211)

Solutions

  1. Set DATA_DIR=/var/lib/spacedrive (or your persisted volume path) when running the release server
  2. Or pass --data-dir /path explicitly on the command line
  3. In containers, mount a volume at that path so data survives restarts
  4. For local debugging only, use a debug build, which defaults to ~/.spacedrive

Example fix

# before: release server started bare
$ ./sd-server
thread 'main' panicked: DATA_DIR must be set in production

# after: explicit data directory
$ DATA_DIR=/var/lib/spacedrive ./sd-server
# or
$ ./sd-server --data-dir /var/lib/spacedrive
Defensive patterns

Strategy: validation

Validate before calling

// Before starting the release server, assert a data dir is resolved
let data_dir = args.data_dir.clone().or_else(|| std::env::var("DATA_DIR").ok().map(PathBuf::from));
let Some(data_dir) = data_dir else {
    eprintln!("DATA_DIR or --data-dir is required in production");
    std::process::exit(2);
};

Prevention

When it happens

Trigger: Running the release binary in a container or systemd service without DATA_DIR; docker run missing -e DATA_DIR; systemd unit missing Environment=; wrapping the binary in a launcher script that drops the environment.

Common situations: First containerized deployment of the server; CI smoke tests using the release build; Nomad/Kubernetes pods without the env var in the spec.

Related errors


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