spacedriveapp/spacedrive · critical · anyhow::Error
Unknown config version: {}
Error message
Unknown config version: {} What it means
app_config.migrate() walks a chain of version steps (v1 through v6, with 6 as terminal) and any other version value falls into the catch-all arm. A version above 6 means the config file was written by a newer build than the one reading it; a garbage value means corruption or hand-editing. Because migrate() fails, config load and daemon startup fail with it.
Source
Thrown at core/src/config/app_config.rs:385
// Migration from v3 to v4: Add multi-stream logging configuration
self.logging = LoggingConfig::default();
self.version = 4;
Ok(())
}
4 => {
// Migration from v4 to v5: Add proxy pairing configuration
self.proxy_pairing = ProxyPairingConfig::default();
self.version = 5;
self.migrate()
}
5 => {
// Migration from v5 to v6: Add Spacebot companion configuration
self.spacebot = SpacebotConfig::default();
self.version = 6;
Ok(())
}
6 => Ok(()), // Already at target version
v => Err(anyhow!("Unknown config version: {}", v)),
}
}
}
View on GitHub (pinned to 6dfeccf211)
Solutions
- Upgrade back to (or past) the version that wrote the config so it understands the version
- Or back up and remove/recreate the config file to reset to defaults (accepting loss of app settings)
- Never share one data dir between old and new builds; use separate --data-dir per version
Example fix
# before: data dir written by newer build sd daemon start # Unknown config version: 7 # after: quarantine old config, start fresh mv ~/.spacedrive/app_config.json ~/.spacedrive/app_config.json.bak sd daemon start
Defensive patterns
Strategy: validation
Validate before calling
fn config_version_supported(path: &std::path::Path) -> anyhow::Result<bool> {
let v: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(path)?)?;
Ok(v.get("version").and_then(|v| v.as_u64()).map_or(false, |n| (1..=6).contains(&n)))
} Type guard
fn is_known_config_version(v: u64) -> bool {
(1..=6).contains(&v)
} Try / catch
match config.migrate() {
Ok(()) => {}
Err(e) if e.to_string().contains("Unknown config version") => {
eprintln!("Config was written by a newer build. Upgrade the daemon, or back up and remove the config to reset.");
std::process::exit(1);
}
Err(e) => return Err(e),
} Prevention
- Never share one data dir between different versions of the daemon; use per-version directories
- Before downgrading, back up the config file so you can restore it when upgrading again
- Make the error message include the supported range (1..=6) and the file path for quick triage
When it happens
Trigger: Downgrading the daemon/CLI after a newer release wrote a v7+ config; two builds of different versions sharing one data dir; manual edits to the version field.
Common situations: Rolling back a release to fix a regression; testing builds side by side against the same data dir; config files synced between machines running different versions.
Related errors
- No library selected. Run 'sd library list' to see available
- No library selected
- No library selected. Use 'sd library switch' to select a lib
- Could not determine home directory
- Could not determine home directory
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/9acfd836827b38a8.
Report an issue: GitHub.