juicedata/juicefs · error

merge sorted records: %s

Error message

merge sorted records: %s

What it means

Wrapped error from the errgroup worker running mergeGcSortedRecords, which merge-scans the externally sorted meta and object records to classify each block as used/trash/pending/leaked. A failure here (sorter read error, corrupted spill file, codec/checksum mismatch, ctx cancellation) aborts the GC before any leaked object is deleted.

Source

Thrown at cmd/gc_external.go:79

		if err := scanGcMetaRecords(sortMetaCtx, m, metaSorter.Input(), stats.slices); err != nil {
			return errors.Errorf("produce meta records: %s", err)
		}
		metaSorter.CloseInput()
		return nil
	})

	eg.Go(func() error {
		defer stats.scanned.Done()
		if err := scanGcObjectRecords(sortCtx, blobWithPrefix, objSorter.Input(), threads, chunkConf.HashPrefix, maxMtime, stats.prefixes, stats.scanned, stats.skipped); err != nil {
			return errors.Errorf("produce object records: %s", err)
		}
		objSorter.CloseInput()
		return nil
	})

	eg.Go(func() error {
		if err := mergeGcSortedRecords(sortCtx, metaSorter, objSorter, chunkConf.BlockSize, stats, leakedObj); err != nil {
			return errors.Errorf("merge sorted records: %s", err)
		}
		return nil
	})

	sortErr := eg.Wait()
	_ = metaSorter.Done()
	_ = objSorter.Done()
	waitLeakedObj()
	if sortErr != nil {
		return sortErr
	}
	return nil
}

func newGcExternalSorters(ctx context.Context, extSortDir string, threads int) (*extsort.Sorter[gcMetaRecord], *extsort.Sorter[gcObjectRecord], error) {
	metaSorter, err := extsort.New(ctx, extsort.Config{
		WorkDir:  extSortDir,
		Name:     "gc-meta",

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Check free space on the ext-sort directory (`df -h <dir>`) and enlarge or relocate it.
  2. Re-run GC after producers succeed — this error often cascades from the meta/object scan errors.
  3. Point --ext-sort at a reliable local disk, not tmpfs or an NFS mount.
  4. Verify no other process removes files from the ext-sort dir during the run.
  5. Check the embedded cause for checksum/codec errors; if present, retry once (transient I/O) then report a bug with logs.

Example fix

// before: tmpfs too small
juicefs gc --ext-sort /tmp/run $META
// after
mkdir -p /var/jfs-gcsort && juicefs gc --ext-sort /var/jfs-gcsort $META
Defensive patterns

Strategy: validation

Validate before calling

DIR=$EXT_SORT_DIR; df --output=avail -B1G "$DIR" | tail -1 | awk '{exit ($1>1024)?0:1}' || { echo 'ext-sort dir needs >1GB free'; exit 1; }

Try / catch

if strings.Contains(out, "merge sorted records:") {
    // check for cascade from producer errors, disk space, or checksum errors; re-run
}

Prevention

When it happens

Trigger: `juicefs gc --ext-sort` during the merge phase: disk holding extSortDir filled or spill files removed, checksum mismatch on a sorter chunk, sorter iterator error, or sortCtx cancelled because the meta/object producer goroutines failed first.

Common situations: ext-sort directory on a small tmpfs running out of space; admin deleting temp files from extSortDir mid-run; disk I/O errors; another goroutine's failure cancelling the shared context.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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