clockworklabs/SpacetimeDB · critical · DBError

mismatched database identity: {} != {}

Error message

mismatched database identity: {} != {}

What it means

RelationalDB::open cross-checks the database identity recorded in the database's persisted metadata (st_module) against the database_identity argument. The error means the commitlog/snapshot being opened belongs to a different database than the identity you passed.

Source

Thrown at crates/engine/src/relational_db.rs:344

        let elapsed_time = start_time.elapsed();
        ENGINE_METRICS
            .replay_total_time_seconds
            .with_label_values(&database_identity)
            .set(elapsed_time.as_secs_f64());

        let db = Self::new(
            database_identity,
            owner_identity,
            inner,
            persistence,
            metrics_recorder_queue,
        );
        db.migrate_system_tables()?;

        if let Some(meta) = db.metadata()? {
            if meta.database_identity != database_identity {
                return Err(anyhow!(
                    "mismatched database identity: {} != {}",
                    meta.database_identity,
                    database_identity
                )
                .into());
            }
            if meta.owner_identity != owner_identity {
                return Err(anyhow!(
                    "mismatched owner identity: {} != {}",
                    meta.owner_identity,
                    owner_identity
                )
                .into());
            }
        };
        let connected_clients = db.connected_clients()?;

        Ok((db, connected_clients))

View on GitHub (pinned to 3653d2ed49)

Solutions

  1. Point the open at the data directory / commitlog that belongs to the passed database_identity
  2. If the directory is the intended one, pass the identity recorded in the persisted metadata instead of the configured one
  3. If the on-disk database is stale and its data is disposable, wipe the directory and let it be recreated under the new identity
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check the snapshot repository's identity before opening
if let Some(repo) = persistence.as_ref().and_then(|p| p.snapshot_repo()) {
    anyhow::ensure!(
        repo.database_identity() == database_identity,
        "data directory belongs to {}", repo.database_identity()
    );
}
let (db, clients) = RelationalDB::open(database_identity, owner_identity, history, persistence, queue, pool)?;

Type guard

fn identities_match(a: Identity, b: Identity) -> bool { a == b }

Try / catch

match RelationalDB::open(database_identity, owner_identity, history, persistence, queue, pool) {
    Err(e) if e.to_string().starts_with("mismatched database identity") => {
        // operator error: wrong data-dir; do not retry with the same arguments
        panic::abort_open_and_alert_operator(e);
    }
    r => r,
}

Prevention

When it happens

Trigger: Opening a commitlog directory or snapshot repository of database A while passing database B's identity; a host routing bug that substitutes the requester's or owner's identity for the database identity; re-using an old data-dir after the database was deleted and recreated with a new identity.

Common situations: Wrong --data-dir / database directory mapping; snapshot files restored into another database's directory; host configuration mixing up identities after database re-creation.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@3653d2ed49 (2026-08-20). Data as JSON: /api/errors/2a71627ef2f76b9e. Report an issue: GitHub.