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
- Retry the deletion later as the message says — the operation is transactional and will succeed when contention subsides.
- Reduce concurrency: run `juicefs gc` from a single client instead of many in parallel.
- Check for another process repeatedly writing/deleting the same chunk (look at DELCHUNK logs) and serialize those workloads.
- 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
- Avoid running multiple concurrent gc/deletion clients on the same volume
- Schedule data deletion during low-write windows
- Monitor Redis latency; slow Redis widens transaction conflict windows
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
- database %s is used by volume %s
- invalid value for delSlices %s: %v
- get chunk result err: %w
- ErrFuncTimeout
- writeend %s: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/9b5d7b4143f57c72.
Report an issue: GitHub.