juicedata/juicefs · error

scan pending slices

Error message

scan pending slices

What it means

Wraps any failure returned by the scan callback while processing a single pending slice during `juicefs gc` (redisMeta.scanPendingSlices). Once the "<id>_<size>" key parsed fine, the scan() function inspects whether the slice's data still exists in object storage; any error from that inspection (metadata lookup, object storage access) is wrapped with this message.

Solutions

  1. Unwrap the error to see the underlying cause (metadata vs object storage) and fix it.
  2. Re-run `juicefs gc`; the scan is resumable and processes keys individually.
  3. Verify object storage connectivity/credentials with `juicefs gc --dry` or a small sync test.
  4. Reduce GC concurrency or run during off-peak if timeouts are the cause.
Defensive patterns

Strategy: retry

Validate before calling

// Verify object storage reachability before gc:
out, err := juicefs.Gc(ctx, meta, true /*dry*/)

Try / catch

err := gc(ctx, meta)
for attempt := 0; err != nil && attempt < 3; attempt++ {
    time.Sleep(backoff(attempt))
    err = gc(ctx, meta) // resumable: already-cleaned keys are skipped
}

Prevention

When it happens

Trigger: `juicefs gc` processing a valid pending-slice key when scan(id, size) returns an error — e.g. chunk/index lookup against the metadata engine failed or object storage was unreachable during the scan.

Common situations: Object storage credentials expired or network outage during GC; metadata engine failures mid-scan; very large pending-slice backlogs timing out.

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/07760d6bedee0fe6. Report an issue: GitHub.

Appendix: source

Thrown at pkg/meta/redis.go:4202

		close(pendingKeys)
	}()

	for key := range pendingKeys {
		ps := strings.Split(key[1:], "_")
		if len(ps) != 2 {
			return fmt.Errorf("invalid key %s", key)
		}
		id, err := strconv.ParseUint(ps[0], 10, 64)
		if err != nil {
			return errors.Wrapf(err, "invalid key %s, fail to parse id", key)
		}
		size, err := strconv.ParseUint(ps[1], 10, 64)
		if err != nil {
			return errors.Wrapf(err, "invalid key %s, fail to parse size", key)
		}
		clean, err := scan(id, uint32(size))
		if err != nil {
			return errors.Wrap(err, "scan pending slices")
		}
		if clean {
			// TODO: m.deleteSlice(id, uint32(size))
			// avoid lint warning
			_ = clean
		}
	}
	return nil
}

func (m *redisMeta) scanPendingFiles(ctx Context, scan pendingFileScan) error {
	if scan == nil {
		return nil
	}

	visited := make(map[Ino]bool)
	start := int64(0)
	const batchSize = 1000

View on GitHub (pinned to c9a67b23e8)