juicedata/juicefs · error

scan trash slices

Error message

scan trash slices: %s

What it means

Wrapped error from `juicefs gc` when `scanTrashSlices` fails. This phase walks the trash directory in the metadata engine to account for (and optionally delete) slices that already sit in trash; a failure here aborts the whole GC run before block scanning starts. The underlying cause (metadata engine outage, interrupted scan, permission problem) is embedded in the message.

Solutions

  1. Check the wrapped root cause after 'scan trash slices:' and verify the metadata engine is reachable and healthy (redis-cli ping / DB connect test).
  2. Re-run `juicefs gc` once the metadata engine is stable; transient engine errors are the most common trigger.
  3. Reduce concurrency (`--threads`) if the engine is timing out under load.
  4. Verify client version matches the metadata engine version (mixed versions can fail scans); upgrade the client if needed.
  5. Enable `--debug` logging to capture the full engine error code.

Example fix

// before
juicefs gc --threads 100 redis://prod:6379/1
// after (reduce load and retry after engine check)
redis-cli -h prod ping
juicefs gc --threads 8 redis://prod:6379/1
Defensive patterns

Strategy: retry

Validate before calling

// before gc: verify metadata engine reachability
if err := m.Shutdown(0); err == nil { /* placeholder */ }
// practical: run 'juicefs status $META_URL' and require exit code 0

Try / catch

// in Go wrapper around the CLI
out, err := exec.Command("juicefs", "gc", metaURL).CombinedOutput()
if err != nil && strings.Contains(string(out), "scan trash slices:") {
    // inspect embedded engine error, back off and retry
}

Prevention

When it happens

Trigger: Running `juicefs gc` when the metadata engine (Redis/SQL/TiKV) errors while listing trash slices — e.g. engine restart mid-scan, connection drop, trash key iteration timeout, or an internal scan error returned by m.ScanTrash-like logic inside scanTrashSlices.

Common situations: Redis evicted keys or restarted during a long GC; PostgreSQL connection pool exhausted; network partition between the client and the metadata engine; running GC against a volume while another client holds conflicting locks; using an old client against a newer metadata layout.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

Thrown at cmd/gc.go:209

		} else {
			logger.Errorf("compact all chunks: %s", st)
		}
		bar.Done()
		spin.Done()
	} else {
		m.OnMsg(meta.CompactChunk, func(args ...interface{}) error {
			return nil // ignore compaction
		})
	}
	if delFlag {
		if st := m.CleanupSlices(c); st != 0 {
			logger.Fatalf("cleanup slices: %s", st)
		}
	}

	stats := newGcStats(progress, extSortDir != "", delSpin, cleanedFileSpin)
	if err := scanTrashSlices(c, m, stats, delFlag, edge); err != nil {
		return errors.Errorf("scan trash slices: %s", err)
	}
	m.WaitDeleteSlices()
	m.OnMsg(meta.DeleteSlice, func(args ...interface{}) error {
		return errors.New("stop deleting slice")
	})

	var gcErr error
	if extSortDir != "" {
		gcErr = gcExternalSort(c, m, &chunkConf, blob, stats, extSortDir, threads, delFlag, maxMtime)
	} else {
		gcErr = gcInMemory(c, m, &chunkConf, blob, stats, threads, delFlag, maxMtime)
	}
	if gcErr == nil {
		stats.finish(delFlag, compact)
	}
	return gcErr
}

View on GitHub (pinned to c9a67b23e8)