stalwartlabs/stalwart · critical
Unknown database schema version, expected {} or below, found
Error message
Unknown database schema version, expected {} or below, found {} What it means
Stalwart's migration tool panics when the database's stored schema version is NEWER than the schema version supported by this binary. Downgrading across schema migrations is unsupported because older code cannot safely read newer table layouts. The panic halts startup/migration before any destructive work is attempted.
Source
Thrown at crates/migration/src/lib.rs:52
}
}
Some(0..=4) => {
abort(concat!(
"You must first upgrade to version 0.15, please read ",
"https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md"
));
}
Some(5) => {
if !server.registry().is_recovery_mode() {
abort(concat!(
"Upgrading to version 0.16 is a multi-step process, please read ",
"https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md"
));
}
}
Some(version) => {
panic!(
"Unknown database schema version, expected {} or below, found {}",
DATABASE_SCHEMA_VERSION, version
);
}
_ => {
if is_new_install(server).await.caused_by(trc::location!())? {
write_schema_version(server).await?;
return Ok(());
} else {
abort(concat!(
"You must first upgrade to version 0.15, please read ",
"https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md"
));
}
}
}
migrate_v0_16(server).await?;View on GitHub (pinned to e962003857)
Solutions
- Run the NEWER Stalwart version that matches the database schema version (check UPGRADING docs for the version that wrote that schema).
- Restore the database from a backup taken before the newer migration ran, then start the older binary.
- Export data with the newer version and re-import into a fresh database initialized by the target version.
- Never attempt to hand-edit the schema version row; this will corrupt data.
Example fix
// before: downgrade binary against migrated DB // docker run stalwartlabs/stalwart:v0.10 -> panics // after: restore pre-migration backup first // docker run stalwartlabs/stalwart:v0.9 with restored data volume
Defensive patterns
Strategy: validation
Validate before calling
// before launching the older binary, compare stored schema version
let stored = server.store().get_version().await?;
if stored > DATABASE_SCHEMA_VERSION {
eprintln!("DB schema {stored} newer than binary {} — do not start", DATABASE_SCHEMA_VERSION);
std::process::exit(1);
} Prevention
- Pin data volumes and binary versions together in deployment manifests.
- Snapshot/backup the database before every Stalwart upgrade.
- Read UPGRADING notes before changing versions in either direction.
- Use immutable image tags; never reuse a data volume across major downgrades.
When it happens
Trigger: Running `try_migrate` against a database whose schema_version row contains a value greater than DATABASE_SCHEMA_VERSION compiled into the binary — i.e. the database was migrated by a newer Stalwart release.
Common situations: Rolling back Stalwart from a newer version to an older one after the newer version already migrated the schema; pointing an older container image at a data volume used by a newer deployment.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Migration aborted: {message}
- Failed to scan keys
- Failed to delete keys
- Failed to deserialize counter/quota
AI-assisted analysis of stalwartlabs/stalwart@e962003857 (2026-09-06).
Data as JSON: /api/errors/029d5137b162284f.
Report an issue: GitHub.