juicedata/juicefs · error
scan trash files
Error message
scan trash files
What it means
When scanning trash files, the per-entry scan callback returned an error; it is wrapped as 'scan trash files'. This propagates a failure from the caller-provided scan function (e.g. writing to a dump/backup target) during trash enumeration.
Source
Thrown at pkg/meta/base.go:3246
func (m *baseMeta) scanTrashFiles(ctx Context, scan trashFileScan) error {
var st syscall.Errno
var entries []*Entry
if st = m.en.doReaddir(ctx, TrashInode, 1, &entries, -1); st != 0 {
return errors.Wrap(st, "read trash")
}
var subEntries []*Entry
for _, entry := range entries {
ts, err := time.Parse("2006-01-02-15", string(entry.Name))
if err != nil {
logger.Warnf("bad entry as a subTrash: %s", entry.Name)
continue
}
if m.getFormat().DirStats {
ds, st := m.GetDirStat(ctx, entry.Inode)
if st == 0 && ds != nil {
if _, err := scan(entry.Inode, uint64(ds.length), ts, ds.inodes); err != nil {
return errors.Wrap(err, "scan trash files")
}
continue
}
logger.Warnf("get dir stat %d: %s, fallback to readdir", entry.Inode, st)
}
subEntries = subEntries[:0]
if st = m.en.doReaddir(ctx, entry.Inode, 1, &subEntries, -1); st != 0 {
logger.Warnf("readdir subEntry %d: %s", entry.Inode, st)
continue
}
for _, se := range subEntries {
if se.Attr.Typ == TypeFile {
clean, err := scan(se.Inode, se.Attr.Length, ts, 1)
if err != nil {
return errors.Wrap(err, "scan trash files")
}
if clean {
// TODO: m.en.doUnlink(ctx, entry.Attr.Parent, string(entry.Name))View on GitHub (pinned to c9a67b23e8)
Solutions
- Inspect the wrapped inner error for the callback's actual failure (disk full, broken pipe, upload error)
- Free space / fix permissions on the dump destination and retry
- If piping, ensure downstream consumers stay alive: juicefs dump ... | gzip > file.gz
- Re-run the dump — it is restartable since it reads metadata non-destructively
Example fix
// before juicefs dump meta.db dump.json // scan trash files: write ...: no space left on device // after df -h /backup && juicefs dump meta.db /backup/dump.json
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure dump destination is writable and has space before scanning
if fi, err := os.Stat(destDir); err != nil || !fi.IsDir() {
// fix destination first
} Try / catch
if err := scanTrashFiles(ctx, scan); err != nil {
// errors.As/wrap reveals the callback's real failure (ENOSPC, broken pipe, upload error)
return err
} Prevention
- Check free space on the dump destination before long trash scans
- Avoid piping dumps into fragile consumers; write to a file instead
- Monitor object-store upload health when backing up to S3-compatible targets
When it happens
Trigger: Running juicefs dump/gc with trash scanning when the scan callback fails — typically the dump destination write fails, or the callback encounters an invalid entry it rejects.
Common situations: Dump target disk full or unwritable during 'juicefs dump'; S3/object store upload failure while backing up trash entries; interrupted pipes (juicefs dump | gzip where gzip dies).
Related errors
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/716bf46750011ccb.
Report an issue: GitHub.