juicedata/juicefs · error

invalid value for delSlices %s: %v

Error message

invalid value for delSlices %s: %v

What it means

During delayed slice-reference cleanup, the stored value of the `delSlices` hash entry for `key` failed to decode into any delayed slice records (decodeDelayedSlices produced an empty list). This indicates the persisted value is corrupt, truncated, or was written by an incompatible/older format, so the cleanup transaction refuses to proceed to avoid decrementing the wrong slice refcounts.

Source

Thrown at pkg/meta/redis.go:3740

				logger.Warnf("Invalid key %s", key)
				continue
			} else if ts >= uint64(edge) {
				continue
			} else if id, e := strconv.ParseUint(ps[0], 10, 64); e != nil {
				logger.Warnf("Invalid key %s", key)
				continue
			} else if err := r.txn(ctx, func(tx *redis.Tx) error {
				ss, rs = ss[:0], rs[:0]
				val, e := tx.HGet(ctx, r.delSlices(), key).Result()
				if e == redis.Nil {
					return nil
				} else if e != nil {
					return e
				}
				buf := []byte(val)
				r.decodeDelayedSlices(buf, &ss)
				if len(ss) == 0 {
					return fmt.Errorf("invalid value for delSlices %s: %v", key, buf)
				}
				_, e = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
					for _, s := range ss {
						rs = append(rs, pipe.HIncrBy(ctx, r.sliceRefs(), r.sliceKey(s.Id, s.Size), -1))
					}
					pipe.HDel(ctx, r.delSlices(), key)
					r.genLog(ctx, pipe, time.Now(), "CLEANUP_DELAYED_SLICES(%d,%d)", id, int64(ts))
					return nil
				})
				return e
			}, r.delSlices()); err != nil {
				logger.Warnf("Cleanup delSlices %s: %s", key, err)
				continue
			}
			for i, s := range ss {
				if rs[i].Err() == nil && rs[i].Val() < 0 {
					r.deleteSlice(s.Id, s.Size)
					count++

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Inspect the value: redis-cli HGET <delSlices-key> <key> and compare against the DelayedSlices encoding used by decodeDelayedSlices.
  2. If the value is corrupt and the corresponding slices are known-deleted, safely remove the hash entry (HDEL) so cleanup stops failing, after confirming slice refcounts are correct.
  3. Upgrade all clients to a version sharing the same delayed-slices encoding, then retry cleanup.
  4. Re-dump/backup metadata to verify overall consistency; run `juicefs fsck`/gc to reconcile slice refcounts.

Example fix

// before: silent proceed on undecodable value
r.decodeDelayedSlices(buf, &ss)
if len(ss) == 0 { return fmt.Errorf("invalid value for delSlices %s: %v", key, buf) }
// after (operator remediation, not code): confirm refcounts then
// redis-cli HDEL <delSlicesKey> <key>
// and run `juicefs gc` to re-verify slice refs
Defensive patterns

Strategy: validation

Validate before calling

val, _ := rdb.HGet(ctx, delSlicesKey, key).Result()
var ss DelayedSlices
decodeDelayedSlices([]byte(val), &ss)
if len(ss) == 0 { fmt.Printf("corrupt delSlices entry %q: %q — reconcile with juicefs gc before cleanup\n", key, val) }

Try / catch

if err := cleanupDelayedSlices(ctx); err != nil && strings.Contains(err.Error(), "invalid value for delSlices") {
    // stop automated cleanup; requires manual reconciliation
    alertOperator(err)
}

Prevention

When it happens

Trigger: A hash entry in the delSlices key whose value is empty or undecodable when the delayed cleanup transaction scans and processes it (e.g. after a manual Redis edit, a restore from a partial backup, or data written by a client version with a different encoding).

Common situations: Restoring metadata from an incomplete dump/backup; hand-editing or flushing parts of Redis; mixing very old client versions that wrote a legacy delSlices format.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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