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

  1. Retry the command once the metadata engine is reachable (the wrapped errno tells which engine call failed)
  2. Check metadata engine health/logs (Redis INFO, MySQL error log)
  3. Reduce load or run maintenance during off-peak hours to avoid engine timeouts
  4. 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

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


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/f74009211704965b. Report an issue: GitHub.