risingwavelabs/risingwave · error · MetaError

use the `mem` backend instead of specifying a URL of…

Error message

use the `mem` backend instead of specifying a URL of in-memory SQLite

What it means

SqlMetaStore::connect explicitly rejects SQLite endpoints that point at an in-memory database (`:memory:` or `mode=memory`). In-memory SQLite is useless for the meta store because each pooled connection gets its own empty database, so users are directed to the dedicated `mem` backend instead.

Solutions

  1. Change the meta backend to `mem` (in-memory meta store) instead of an in-memory SQLite URL.
  2. If persistence is needed, use a file-backed SQLite URL (e.g. `sqlite://path/to/meta.db`) or Postgres.
  3. Update the RisingWave config `meta.with_backend`/endpoint accordingly and restart.

Example fix

// before
endpoint = "sqlite://:memory:"
// after
backend = "mem"  // or endpoint = "sqlite://./meta.db" for persistence
Defensive patterns

Strategy: validation

Validate before calling

fn valid_meta_endpoint(ep: &str) -> bool {
    !(ep.starts_with("sqlite") && (ep.contains(":memory:") || ep.contains("mode=memory")))
}

Type guard

fn is_in_memory_sqlite(ep: &str) -> bool {
    ep.contains(":memory:") || ep.contains("mode=memory")
}

Prevention

When it happens

Trigger: Configuring the meta store with a SQLite URL like `sqlite://:memory:` or containing `mode=memory` and calling connect().

Common situations: Dev/test config mistakes where someone points the meta backend at in-memory SQLite instead of using the built-in in-memory meta backend.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/bf0a6f8f9baa2e1c. Report an issue: GitHub.

Appendix: source

Thrown at src/meta/src/controller/mod.rs:121

                let conn = sea_orm::Database::connect(options).await?;
                Self {
                    conn,
                    endpoint: IN_MEMORY_STORE.to_owned(),
                }
            }
            MetaStoreBackend::Sql { endpoint, config } => {
                let mut options = ConnectOptions::new(endpoint.clone());
                options
                    .max_connections(config.max_connections)
                    .min_connections(config.min_connections)
                    .connect_timeout(Duration::from_secs(config.connection_timeout_sec))
                    .idle_timeout(Duration::from_secs(config.idle_timeout_sec))
                    .acquire_timeout(Duration::from_secs(config.acquire_timeout_sec));

                if DbBackend::Sqlite.is_prefix_of(&endpoint) {
                    if endpoint.contains(":memory:") || endpoint.contains("mode=memory") {
                        bail!(
                            "use the `mem` backend instead of specifying a URL of in-memory SQLite"
                        );
                    }
                    options.sqlite_common();
                }

                let conn = sea_orm::Database::connect(options).await?;
                Self { conn, endpoint }
            }
        })
    }

    #[cfg(any(test, feature = "test"))]
    pub async fn for_test() -> Self {
        let this = Self::connect(MetaStoreBackend::Mem).await.unwrap();
        Migrator::up(&this.conn, None).await.unwrap();
        this
    }

View on GitHub (pinned to 6469eb736d)