juicedata/juicefs · error

delete slice from chunk %s fail: %s, retry later

Error message

delete slice from chunk %s fail: %s, retry later

What it means

In deleteSlices/legacy slice deletion, the transaction that decrements chunk slice references (via a Redis transaction/watch on the chunk key) failed and was retried without success. The message explicitly says 'retry later' because the reference-count update for that chunk was not committed; slice data is not considered deleted and refcounts remain consistent.

Source

Thrown at pkg/meta/redis.go:3656

		slices := readSlices(vals)
		if slices == nil {
			logger.Errorf("Corrupt value for inode %d chunk index %d, use `gc` to clean up leaked slices", inode, indx)
		}
		_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
			pipe.Del(ctx, key)
			for _, s := range slices {
				if s.id > 0 {
					todel = append(todel, s)
					rs = append(rs, pipe.HIncrBy(ctx, m.sliceRefs(), m.sliceKey(s.id, s.size), -1))
				}
			}
			m.genLog(ctx, pipe, time.Now(), "DELCHUNK(%d,%d)", inode, indx)
			return nil
		})
		return err
	}, key)
	if err != nil {
		return fmt.Errorf("delete slice from chunk %s fail: %s, retry later", key, err)
	}
	for i, s := range todel {
		if rs[i].Val() < 0 {
			m.deleteSlice(s.id, s.size)
		}
	}
	return nil
}

func (m *redisMeta) doDeleteFileData(inode Ino, length uint64) {
	m.doDeleteFileData_(inode, length, "")
}

func (m *redisMeta) doDeleteFileData_(inode Ino, length uint64, tracking string) {
	var ctx = Background()
	var indx uint32
	p := m.rdb.Pipeline()
	for uint64(indx)*ChunkSize < length {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Retry the deletion later as the message says — the operation is transactional and will succeed when contention subsides.
  2. Reduce concurrency: run `juicefs gc` from a single client instead of many in parallel.
  3. Check for another process repeatedly writing/deleting the same chunk (look at DELCHUNK logs) and serialize those workloads.
  4. Verify Redis health/latency; slow or flapping Redis increases transaction conflict windows.
Defensive patterns

Strategy: retry

Try / catch

if err := gcSlices(ctx); err != nil && strings.Contains(err.Error(), "delete slice from chunk") {
    time.Sleep(backoff) // message explicitly says retry later
    return gcSlices(ctx)
}

Prevention

When it happens

Trigger: Concurrent modification of the same chunk (another client deleting slices or writing to the same chunk) causing the watch/transaction on the chunk key to keep conflicting until the retry budget is exhausted.

Common situations: Heavy concurrent `juicefs gc` or data deletion from multiple clients touching the same chunk; long-running transactions on a busy Redis; network flaps mid-transaction.

Related errors


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