spacedriveapp/spacedrive · error
Failed to get metadata via backend: {}
Error message
Failed to get metadata via backend: {} What it means
Thrown by should_filter_path when the VolumeBackend's metadata() call fails while change detection decides whether a path is filtered. The backend abstraction fronts non-local volumes (removable/network), so any I/O failure at the metadata call is wrapped here. The path never gets evaluated against the ruler because the kind/size/modified data it needs could not be fetched.
Source
Thrown at core/src/ops/indexing/change_detection/handler.rs:127
}
}
}
}
/// Evaluates indexing rules to determine if a path should be skipped.
pub async fn should_filter_path(
path: &Path,
rule_toggles: RuleToggles,
location_root: &Path,
backend: Option<&Arc<dyn crate::volume::VolumeBackend>>,
) -> Result<bool> {
let ruler = build_default_ruler(rule_toggles, location_root, path).await;
let metadata = if let Some(backend) = backend {
backend
.metadata(path)
.await
.map_err(|e| anyhow::anyhow!("Failed to get metadata via backend: {}", e))?
} else {
let fs_meta = tokio::fs::metadata(path).await?;
crate::volume::backend::RawMetadata {
kind: if fs_meta.is_dir() {
EntryKind::Directory
} else if fs_meta.is_symlink() {
EntryKind::Symlink
} else {
EntryKind::File
},
size: fs_meta.len(),
modified: fs_meta.modified().ok(),
created: fs_meta.created().ok(),
accessed: fs_meta.accessed().ok(),
inode: None,
permissions: None,
}
};View on GitHub (pinned to 6dfeccf211)
Solutions
- Verify the volume is still mounted (re-run volume detection) before starting or resuming change detection for this location
- Check the VolumeBackend implementation's own logs for the underlying I/O error this message wraps
- If the volume is gone, cancel/abort the indexing job for that location rather than retrying the same path
- For local filesystems, pass None as backend so the tokio::fs::metadata fallback path is used
Example fix
// before
let metadata = backend
.metadata(path)
.await
.map_err(|e| anyhow::anyhow!("Failed to get metadata via backend: {}", e))?;
// after: include the path so operators can tell which volume/file died
let metadata = backend
.metadata(path)
.await
.map_err(|e| anyhow::anyhow!("Failed to get metadata via backend for {}: {} (is the volume still mounted?)", path.display(), e))?; Defensive patterns
Strategy: validation
Validate before calling
// Before indexing/change detection, confirm the volume answers metadata at the root
if let Some(backend) = &backend {
if backend.metadata(location_root).await.is_err() {
// volume is unreachable; abort the scan for this location instead of per-path failures
return Ok(());
}
} Try / catch
match should_filter_path(path, toggles, root, backend.as_deref()).await {
Ok(filtered) => { /* continue */ }
Err(e) if e.to_string().contains("Failed to get metadata via backend") => {
tracing::warn!(error = %e, "volume metadata failed; skipping path and marking volume suspect");
}
Err(e) => return Err(e),
} Prevention
- Run volume detection/mount checks before every indexing session on removable or network volumes
- Watch for volume-removal events and cancel in-flight indexing jobs for that location
- Prefer passing None for purely local locations so the tokio::fs path is used
When it happens
Trigger: Calling should_filter_path with Some(backend) while the volume behind that backend is unavailable: backend.metadata(path) returns Err. Typical when an indexer or watcher event fires after a USB eject, an SMB/NFS disconnect, or a permission change on the mount root.
Common situations: Removable drive unplugged mid-index; network share offline at scan time; a VolumeBackend instance kept alive after the volume was unmounted; watcher events queued from a device that disappeared before processing.
Related errors
- Volume not mounted, cannot verify path existence
- Cannot access path: {}
- Library not found: {}
- Location not found: {}
- Location {} has no root entry
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/a06ca2c1b86f74d8.
Report an issue: GitHub.