tursodatabase/turso · error

Unable to access database schema. The database may be using

Error message

Unable to access database schema. The database may be using an older SQLite version or may not be properly initialized.

What it means

While executing '.indexes', the CLI selects index names from sqlite_schema. When the engine reports 'no such table: sqlite_schema', the CLI maps it to this message: the database's schema catalog itself is unreadable, which happens with pre-3.3.0 SQLite files (which only expose sqlite_master) or with a file that is not a properly initialized SQLite database.

Source

Thrown at cli/app.rs:1636

                Some(ref tbl_name) => format!(
                    "SELECT name FROM {name}.sqlite_schema WHERE type='index' AND tbl_name = '{tbl_name}' ORDER BY 1"
                ),
                None => format!("SELECT name FROM {name}.sqlite_schema WHERE type='index' ORDER BY 1"),
            };
            let handler = |row: &turso_core::Row| {
                if let Ok(Value::Text(idx)) = row.get::<&Value>(0) {
                    if let Some(prefix) = prefix {
                        indexes.push_str(prefix);
                        indexes.push('.');
                    }
                    indexes.push_str(idx.as_str());
                    indexes.push(' ');
                }
                Ok(())
            };
            if let Err(err) = self.handle_row(&sql, handler) {
                if err.to_string().contains("no such table: sqlite_schema") {
                    return Err(anyhow::anyhow!("Unable to access database schema. The database may be using an older SQLite version or may not be properly initialized."));
                } else {
                    return Err(anyhow::anyhow!("Error querying schema: {}", err));
                }
            }
        }
        if !indexes.is_empty() {
            let _ = self.writeln(indexes.trim_end().as_bytes());
        }
        Ok(())
    }

    fn display_tables(&mut self, pattern: Option<&str>) -> anyhow::Result<()> {
        let mut tables = String::new();

        for name in self.database_names()? {
            let prefix = (name != "main").then_some(&name);
            let sql = match pattern {
                Some(pattern) => format!(

View on GitHub (pinned to bad083fafb)

Solutions

  1. Verify the file is a SQLite database: check for the 16-byte header 'SQLite format 3\0' (e.g. 'file mydb' or 'head -c 16 mydb').
  2. Try the legacy catalog name: SELECT name FROM sqlite_master; — older databases only have that table.
  3. Modernize the file: open it with the sqlite3 shell and pipe '.dump' into a fresh database, then use the new file.
  4. Reopen the database from a fresh CLI session to rule out a transient open failure.

Example fix

-- before
.indexes
-- Error: Unable to access database schema. ...

-- after: rebuild the catalog in a modern file
-- (in sqlite3 shell) .open legacy.db  |  .dump | sqlite3 new.db
-- then: tursodb new.db -c '.indexes'
Defensive patterns

Strategy: validation

Validate before calling

-- Probe the catalog before running .indexes:
SELECT 1 FROM sqlite_schema LIMIT 1;      -- modern name
SELECT 1 FROM sqlite_master LIMIT 1;      -- legacy fallback

Try / catch

// On the 'Unable to access database schema' error, retry the query against
// the legacy catalog before giving up:
if err.to_string().contains("Unable to access database schema") {
    let names = query_legacy_sqlite_master()?;
}

Prevention

When it happens

Trigger: Running '.indexes' on a very old SQLite database file, on a file that is not a SQLite database at all (random bytes, wrong format), or in an engine state where the schema table cannot be resolved.

Common situations: Pointing the CLI at a legacy export or an unrelated binary file; a zero-length or header-only file created by a failed open; version-skew where an old tool wrote a sqlite_master-only catalog.

Related errors


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/f2a09c7d9c361959. Report an issue: GitHub.