clockworklabs/SpacetimeDB · error · io::Error
repo {}: error getting file metadata for segment {}: {}
Error message
repo {}: error getting file metadata for segment {}: {} What it means
While checking whether a segment file already exists, fs::metadata on the segment path returned an error other than NotFound (which is the normal, handled 'segment absent' case). The original ErrorKind and message are passed through, so the real cause - PermissionDenied, EIO, path issues - is in the inner error text.
Source
Thrown at crates/commitlog/src/repo/fs.rs:266
warn!("repo {}: failed to remove {}: {}", self, lock_path.display(), e);
}
},
);
// Check whether the segment already exists.
// Overwrite it if its length is zero.
match fs::metadata(&path) {
Ok(stat) => {
if stat.len() > 0 {
return Err(io::Error::new(
io::ErrorKind::AlreadyExists,
format!("repo {}: segment {} already exists and is non-empty", self, offset),
));
}
}
Err(e) => {
if e.kind() != io::ErrorKind::NotFound {
return Err(io::Error::new(
e.kind(),
format!(
"repo {}: error getting file metadata for segment {}: {}",
self, offset, e
),
));
}
}
}
// The segment file either does not exist, or is of length zero.
// Write the header to a temporary file and atomically move it into place.
let mut tmp = tempfile::Builder::new().make_in(&self.root.0, |tmp_path| {
File::options().read(true).write(true).create_new(true).open(tmp_path)
})?;
header.write(&mut tmp)?;
tmp.as_file_mut().sync_all()?;
let segment = tmp.persist(path)?;View on GitHub (pinned to 524b4487d9)
Solutions
- Read the inner {e} and its ErrorKind: fix directory permissions or path components accordingly
- If the kind is EIO, check device/dmesg health and remount the filesystem
- Reproduce as the same user with `stat <segment path>` to confirm it is environmental
Defensive patterns
Strategy: try-catch
Validate before calling
// smoke-test the path before opening the log
std::fs::metadata(&dir).and_then(|m| {
if m.is_dir() { Ok(()) } else { Err(io::Error::new(io::ErrorKind::NotFound, "not a directory")) }
})?; Type guard
fn is_segment_metadata_error(e: &io::Error) -> bool {
e.to_string().contains("error getting file metadata for segment")
} Try / catch
match result {
Ok(v) => v,
Err(e) if is_segment_metadata_error(&e) => {
// surface the inner kind (PermissionDenied, EIO, ...) for the operator
return Err(io::Error::new(e.kind(), format!("stat failed on log segment: {e}")));
}
Err(e) => return Err(e),
} Prevention
- Run the process as a user that owns the log directory
- Avoid NFS/FUSE mounts for the log when possible; if used, monitor for EIO
- Add a start-up health check that stats every file in the log directory
When it happens
Trigger: create_segment stats <dir>/<segment> and the stat itself fails: missing execute permission on a path component, an I/O error from the device, or a path that exceeds filesystem limits.
Common situations: Running as a non-root user on root-owned directories; flaky NFS/FUSE mounts returning EIO on stat; exotic path configurations.
Related errors
- repo {}: {}: {}
- AlreadyExists
- repo {}: segment {} already exists and is non-empty: {}
- error reading commit header: {e}
- failed to read {} bytes of commit payload: {}
AI-assisted analysis of clockworklabs/SpacetimeDB@524b4487d9 (2026-08-16).
Data as JSON: /api/errors/c69f90fd0b48d3aa.
Report an issue: GitHub.