{"record":{"id":"9b5d7b4143f57c72","repo":"juicedata/juicefs","slug":"delete-slice-from-chunk-s-fail-s-retry-later","errorCode":null,"errorMessage":"delete slice from chunk %s fail: %s, retry later","messagePattern":"delete slice from chunk (.+?) fail: (.+?), retry later","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/redis.go","lineNumber":3656,"sourceCode":"\t\tslices := readSlices(vals)\n\t\tif slices == nil {\n\t\t\tlogger.Errorf(\"Corrupt value for inode %d chunk index %d, use `gc` to clean up leaked slices\", inode, indx)\n\t\t}\n\t\t_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {\n\t\t\tpipe.Del(ctx, key)\n\t\t\tfor _, s := range slices {\n\t\t\t\tif s.id > 0 {\n\t\t\t\t\ttodel = append(todel, s)\n\t\t\t\t\trs = append(rs, pipe.HIncrBy(ctx, m.sliceRefs(), m.sliceKey(s.id, s.size), -1))\n\t\t\t\t}\n\t\t\t}\n\t\t\tm.genLog(ctx, pipe, time.Now(), \"DELCHUNK(%d,%d)\", inode, indx)\n\t\t\treturn nil\n\t\t})\n\t\treturn err\n\t}, key)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"delete slice from chunk %s fail: %s, retry later\", key, err)\n\t}\n\tfor i, s := range todel {\n\t\tif rs[i].Val() < 0 {\n\t\t\tm.deleteSlice(s.id, s.size)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (m *redisMeta) doDeleteFileData(inode Ino, length uint64) {\n\tm.doDeleteFileData_(inode, length, \"\")\n}\n\nfunc (m *redisMeta) doDeleteFileData_(inode Ino, length uint64, tracking string) {\n\tvar ctx = Background()\n\tvar indx uint32\n\tp := m.rdb.Pipeline()\n\tfor uint64(indx)*ChunkSize < length {","sourceCodeStart":3638,"sourceCodeEnd":3674,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/redis.go#L3638-L3674","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := gcSlices(ctx); err != nil && strings.Contains(err.Error(), \"delete slice from chunk\") {\n    time.Sleep(backoff) // message explicitly says retry later\n    return gcSlices(ctx)\n}","preventionTips":["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"],"tags":["redis","transaction","conflict","chunk","refcount"],"backgroundTag":"database-write-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}