Skip to content

VolumeNotFound error when data path contains spaces #1011

@jacoblyles

Description

@jacoblyles

Describe the bug
RustFS fails to start with VolumeNotFound error when the data directory path contains spaces (e.g., /Users/user/Library/Application Support/rustfs-data).

To Reproduce

$ mkdir -p "/tmp/path with spaces/data"
$ rustfs --address 0.0.0.0:9000 --access-key key --secret-key secret "/tmp/path with spaces/data"

returns Error: DiskError(VolumeNotFound)

Expected behavior
RustFS starts successfully and serves the directory.

Desktop (please complete the following information):

  • macOS
  • RustFS version: 0.0.5 (current main branch)

Additional context
In crates/ecstore/src/disk/endpoint.rs, the get_file_path() function returns the URL-encoded path without decoding it. When a path like /tmp/path with spaces/data is converted to a file:// URL internally, spaces become %20:
file:///tmp/path%20with%20spaces/data
The get_file_path() function returns url.path() directly, which gives the encoded string /tmp/path%20with%20spaces/data. Later in crates/ecstore/src/disk/local.rs:141, this path is passed to std::fs::canonicalize():

let root = match std::fs::canonicalize(ep.get_file_path()) {
    Ok(path) => path,
    Err(e) => {
        if e.kind() == ErrorKind::NotFound {
            return Err(DiskError::VolumeNotFound);  // <-- This error
        }
        ...
    }
};

canonicalize() looks for a directory literally named path%20with%20spaces (with the percent signs), which doesn't exist, causing VolumeNotFound.

Suggested Fix
Decode percent-encoded characters in get_file_path():

pub fn get_file_path(&self) -> String {
    let path = self.url.path();
    // Decode percent-encoded characters (e.g., %20 -> space)
    let decoded = urlencoding::decode(path)
        .unwrap_or_else(|_| std::borrow::Cow::Borrowed(path));
    
    #[cfg(windows)]
    if self.url.scheme() == "file" {
        let stripped = decoded.strip_prefix('/').unwrap_or(&decoded);
        return stripped.to_string();
    }
    
    decoded.into_owned()
}

Note: This changes the return type from &str to String, which requires updating call sites in endpoints.rs to use String instead of &str for the path_ip_map HashMap key type.

Metadata

Metadata

Assignees

Labels

S-resolvingStatus: Resolving a issuecommunityImprovement for open source community

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions