risingwavelabs/risingwave · error

Root directory does not exist: {}

Error message

Root directory does not exist: {}

What it means

list_splits for the batch POSIX FS source checks that the configured root directory exists before emitting its single dummy split. If Path::new(root).exists() is false, it refuses to proceed with this error naming the configured root path. It is a fail-fast guard against scanning a non-existent directory.

Source

Thrown at src/connector/src/source/filesystem/opendal_source/batch_posix_fs_source.rs:119

#[async_trait]
impl SplitEnumerator for BatchPosixFsEnumerator {
    type Properties = BatchPosixFsProperties;
    type Split = BatchPosixFsSplit;

    async fn new(
        properties: Self::Properties,
        _context: SourceEnumeratorContextRef,
    ) -> ConnectorResult<Self> {
        Ok(Self { properties })
    }

    async fn list_splits(&mut self) -> ConnectorResult<Vec<BatchPosixFsSplit>> {
        // dummy list, just return one split
        let root_path = Path::new(&self.properties.root);

        if !root_path.exists() {
            return Err(anyhow!("Root directory does not exist: {}", self.properties.root).into());
        }

        // For batch source, we return exactly one split representing all files to be processed.
        Ok(vec![BatchPosixFsSplit::new(
            self.properties.root.clone(), // file_path is the root
            "114514".into(),              // split_id does not matter
        )])
    }
}

/// Reader for batch posix fs source
#[derive(Debug)]
pub struct BatchPosixFsReader {}

#[async_trait]
impl SplitReader for BatchPosixFsReader {
    type Properties = BatchPosixFsProperties;
    type Split = BatchPosixFsSplit;

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Verify the path in the error message exists on the node: run `ls` on it from the same host/container as the compute node.
  2. Fix the source's root/MATCH_PATTERN property if it's a typo (recreate or alter the source).
  3. Mount the missing volume/shared filesystem into the container running RisingWave.
  4. Check permissions - a path you can't stat may report as non-existent; ensure read access on parent directories.

Example fix

-- before
CREATE SOURCE s (...) WITH (connector = 'filesystem', match_pattern = 'data/events/*.parquet')
-- after (path actually exists / mounted)
CREATE SOURCE s (...) WITH (connector = 'filesystem', match_pattern = '/mnt/data/events/*.parquet')
Defensive patterns

Strategy: validation

Validate before calling

// shell check before creating the source
ls /mnt/data/events/*.parquet || echo "root path missing"
# or in SQL, test with a select on an existing source path first

Try / catch

// caller (Rust)
match enumerator.list_splits().await {
    Ok(splits) => splits,
    Err(e) if e.to_string().contains("Root directory does not exist") => {
        eprintln!("mount/fix root path first: {e}"); Vec::new()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Creating/starting a filesystem batch source whose MATCH_PATTERN/root path (self.properties.root) points to a directory that does not exist on the compute node, e.g. before mounting the volume or with a typo'd path.

Common situations: Typo in the s3/posix root path; shared filesystem (NFS/EFS) not mounted on the node running the source; container missing the volume mount; path deleted after source creation.

Related errors


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