juicedata/juicefs · error
read trash
Error message
read trash
What it means
scanTrashFiles lists the trash directory via doReaddir on the TrashInode; a non-zero errno from the metadata engine is wrapped as 'read trash'. It means the trash area of the filesystem could not be enumerated in the metadata engine.
Source
Thrown at pkg/meta/base.go:3233
if st = m.emptyDir(ctx, e.Inode, true, &count, concurrent); st != 0 {
if st != syscall.ETIMEDOUT && st != syscall.EINTR {
logger.Warnf("empty subTrash %d/%s: %s", e.Inode, e.Name, st)
}
} else {
entries = entries[1:]
if st = m.en.doRmdir(ctx, TrashInode, string(e.Name), nil, nil); st != 0 {
logger.Warnf("rmdir subTrash %s: %s", e.Name, st)
}
}
}
return 0
}
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)
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Retry the command once the metadata engine is reachable (the wrapped errno tells which engine call failed)
- Check metadata engine health/logs (Redis INFO, MySQL error log)
- Reduce load or run maintenance during off-peak hours to avoid engine timeouts
- If a specific engine error persists (e.g. corrupt data), restore metadata from backup
Example fix
// before juicefs gc redis://remote:6379/1 // read trash: connection timed out // after: ensure reachability / retry redis-cli -h remote ping && juicefs gc redis://remote:6379/1
Defensive patterns
Strategy: retry
Validate before calling
if err := client.Ping(); err != nil {
// metadata engine down; trash scan will fail with 'read trash'
} Try / catch
if err := scanTrashFiles(ctx, scan); err != nil {
if isTransient(err) { // e.g. timeouts, connection reset
time.Sleep(backoff)
err = scanTrashFiles(ctx, scan)
}
} Prevention
- Run trash scans with generous engine timeouts and retries enabled
- Schedule maintenance during low metadata-engine load
- Keep metadata engine and client on the same network region
When it happens
Trigger: Running trash-related maintenance (e.g. juicefs gc or dump with trash scanning) when the metadata engine errors on readdir of the trash inode — connection failure, timeout, or corrupt internal state.
Common situations: Metadata engine under load or restarted mid-scan; Redis/MySQL connection drops during long trash scans; network timeouts to a remote metadata server.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- readdir inode %d: %s
- statistic: %v
- scan trash files
- invalid dumped meta: missing 'Counters'
- no quota for any trash directory
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/f74009211704965b.
Report an issue: GitHub.