linera-io/linera-protocol · error
failed to check SQLite database existence. file: {database_u
Error message
failed to check SQLite database existence. file: {database_url}, error: {e} What it means
Before creating or opening its SQLite file, the indexer probes whether the path exists; if that probe itself returns an error (as opposed to a clean yes/no), the constructor panics. This means the filesystem could not answer 'does this file exist' — typically because a path component is unreadable, a component is a plain file rather than a directory, or the path traverses a directory without search (execute) permission.
Source
Thrown at linera-indexer/lib/src/db/sqlite/mod.rs:80
}
impl SqliteDatabase {
/// Creates a new SQLite database connection.
pub async fn new(database_url: &str) -> Result<Self, SqliteError> {
if !database_url.contains("memory") {
match std::fs::exists(database_url) {
Ok(true) => {
tracing::info!(?database_url, "opening existing SQLite database");
}
Ok(false) => {
tracing::info!(?database_url, "creating new SQLite database");
// Create the database file if it doesn't exist
std::fs::File::create(database_url).unwrap_or_else(|e| {
panic!("failed to create SQLite database file: {database_url}, error: {e}")
});
}
Err(e) => {
panic!(
"failed to check SQLite database existence. file: {database_url}, error: {e}"
)
}
}
}
let pool = SqlitePoolOptions::new()
.max_connections(5)
.connect(database_url)
.await
.map_err(SqliteError::Database)?;
let db = Self { pool };
db.initialize_schema().await?;
Ok(db)
}
/// Initialize the database schema
async fn initialize_schema(&self) -> Result<(), SqliteError> {
// Create core tablesView on GitHub (pinned to 6c226ddcb3)
Solutions
- Verify each component of the path is a directory and traversable: namei -l /path/to/indexer.db shows the first failing component
- Fix permissions on the failing component (chmod o+x or chown) or choose a path you fully own
- Remove stale file-where-a-directory-is-expected components
- If on a network mount, ensure it is mounted and healthy before starting the indexer
Example fix
# before (parent dir not traversable by the service user) sudo -u indexer linera-indexer --database /home/deploy/indexer.db # after sudo mkdir -p /var/lib/linera-indexer && sudo chown indexer /var/lib/linera-indexer sudo -u indexer linera-indexer --database /var/lib/linera-indexer/indexer.db
Defensive patterns
Strategy: validation
Validate before calling
let path = std::path::Path::new(database_url);
for ancestor in path.ancestors().skip(1) {
match std::fs::metadata(ancestor) {
Ok(md) if md.is_dir() => {}
Ok(_) => panic!("{ancestor} is a file, not a directory"),
Err(e) => panic!("cannot stat {ancestor}: {e}"),
}
} Prevention
- Check traversability of every path component with namei -l when provisioning
- Avoid database paths that traverse other users' home directories
- Mount and verify network volumes before starting the service
When it happens
Trigger: Database path like /root/data/indexer.db when /root is mode 700 and the process runs as another user; a path component that is a regular file (e.g. data.txt/indexer.db); path on a failing/unmounted NFS or FUSE mount. Distinguished from error 21: here the stat/existence check fails, not the create.
Common situations: Running under a container service account with restricted home directories; stale absolute paths baked into config files after a directory layout change; security-hardened systems with restrictive parent-directory modes.
Related errors
- failed to create SQLite database file: {database_url}, error
- Invalid options file format: \n {options_string}
- Invalid RUST_LOG_FORMAT: `{format}`. Valid values are `json
- test-log: RUST_LOG_SPAN_EVENTS must contain filters separate
- Cannot process inbox for follow-only chain {chain_id}. Use `
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/e733991e67001463.
Report an issue: GitHub.