risingwavelabs/risingwave · error · StreamExecutorError

Root directory does not exist

Error message

Root directory does not exist: {}

What it means

The POSIX filesystem batch list source validates that the configured root directory exists on the filesystem before enumerating files. If Path::exists() is false — directory missing, deleted, unmounted, or a typo in configuration — it returns this error naming the root path, aborting the batch scan before any glob matching happens.

Solutions

  1. Verify the path exists on the compute node: check for container/host path mismatches and mount the directory into the pod/container if needed
  2. Correct typos in the source/root configuration and re-run
  3. Restore or recreate the missing directory, or point the source at an existing path
  4. Check filesystem mounts and permissions (NFS/EBS/local) if the path exists elsewhere but not on the node

Example fix

// before
CREATE SOURCE ... WITH (connector = 'posix_fs', root = '/data/exports')  -- path missing on node
// after
CREATE SOURCE ... WITH (connector = 'posix_fs', root = '/mnt/data/exports')  -- verified path, mounted on node
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn root_dir_exists(root: &str) -> bool {
    Path::new(root).is_dir()
}
// call before creating the source / running the scan:
assert!(root_dir_exists("/mnt/data/exports"), "root directory missing");

Type guard

fn is_existing_dir(p: &str) -> bool {
    std::path::Path::new(p).is_dir()
}

Try / catch

match list_files_to_stream(root, pattern) {
    Err(e) if e.to_string().starts_with("Root directory does not exist") => {
        eprintln!("check the source 'root' path and node mounts: {e}");
    }
    other => other?,
}

Prevention

When it happens

Trigger: list_files_to_stream is called with a root: String whose Path::new(&root).exists() is false: the directory does not exist at scan time on the node running the executor.

Common situations: Typo in the CONNECTOR path, directory deleted or renamed between source creation and scan, running in a container where the host path isn't mounted, permission or mount failure making the path invisible.

Related errors


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

Appendix: source

Thrown at src/stream/src/executor/source/batch_source/batch_posix_fs_list.rs:97

            stream_source_core,
            metrics,
            barrier_receiver: Some(barrier_receiver),
            system_params,
            rate_limit_rps,
            barrier_manager,
            associated_table_id: associated_table_id.unwrap(),
        }
    }

    /// List all files from root directory and convert them to a stream of chunks
    async fn list_files_to_stream(
        root: String,
        pattern: Option<String>,
    ) -> StreamExecutorResult<impl Iterator<Item = StreamExecutorResult<StreamChunk>>> {
        // List all files from the root directory
        let root_path = Path::new(&root);
        if !root_path.exists() {
            return Err(anyhow!("Root directory does not exist: {}", root).into());
        }

        // Convert pattern string to glob::Pattern if provided
        let glob_pattern = pattern
            .as_ref()
            .map(|p| GlobPattern::new(p))
            .transpose()
            .with_context(|| format!("Invalid match_pattern: {:?}", pattern))?;

        let mut files = Vec::new();
        Self::collect_files_recursive(root_path, root_path, &glob_pattern, &mut files).await?;

        tracing::debug!(
            "BatchPosixFsListExecutor listed {} files from {}: {:?}",
            files.len(),
            root,
            files
        );

View on GitHub (pinned to 6469eb736d)