juicedata/juicefs · error
remove dir stats
Error message
remove dir stats
What it means
This error is returned from redisMeta.doInit when the format update path tries to remove legacy dir-stat keys (dirUsedInodesKey/dirUsedSpaceKey) inside a Redis transaction and the TxPipelined call fails. JuiceFS disables dir stats when upgrading from a format that had them, and removal of the obsolete counters must succeed for init to proceed.
Source
Thrown at pkg/meta/redis.go:355
body, err := m.rdb.Get(ctx, m.setting()).Bytes()
if err != nil && err != redis.Nil {
return err
}
if err == nil {
var old Format
err = json.Unmarshal(body, &old)
if err != nil {
return fmt.Errorf("existing format is broken: %s", err)
}
if !old.DirStats && format.DirStats {
// remove dir stats as they are outdated
_, err := m.rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Del(ctx, m.dirUsedInodesKey(), m.dirUsedSpaceKey())
m.genLog(ctx, pipe, time.Now(), "INIT_ENABLE_DIRSTATS()")
return nil
})
if err != nil {
return errors.Wrap(err, "remove dir stats")
}
}
if !old.UserGroupQuota && format.UserGroupQuota {
// remove user group quota as they are outdated
_, err := m.rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
pipe.Del(ctx, m.userQuotaKey(), m.userQuotaUsedSpaceKey(), m.userQuotaUsedInodesKey(),
m.groupQuotaKey(), m.groupQuotaUsedSpaceKey(), m.groupQuotaUsedInodesKey())
m.genLog(ctx, pipe, time.Now(), "INIT_ENABLE_USERGROUPQUOTA()")
return nil
})
if err != nil {
return errors.Wrap(err, "remove user group quota")
}
}
if err = format.update(&old, force); err != nil {
return errors.Wrap(err, "update format")
}
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Retry the mount once Redis connectivity is restored; doInit re-runs the removal transaction.
- Verify the Redis instance is writable (not a READONLY replica) and that the key exists on the primary in cluster mode.
- Check Redis logs for OOM or maxmemory errors blocking writes.
- If the keys are already gone, confirm the format was updated and the mount will skip this branch.
Defensive patterns
Strategy: retry
Validate before calling
// Confirm the Redis endpoint is writable before mounting:
if err := rdb.Ping(ctx).Err(); err != nil { return err }
// role_check via INFO replication: skip READONLY replicas Try / catch
if err := doInit(ctx, format); err != nil {
if strings.Contains(err.Error(), "remove dir stats") {
time.Sleep(backoff); return doInit(ctx, format) // transient Redis failure
}
return err
} Prevention
- Point mounts at the Redis primary, never a READONLY replica.
- Check Redis maxmemory/OOM logs before format changes.
- Verify format changes via `juicefs status` before mounting clients.
- Use stable Redis cluster topology (no failover mid-mount).
When it happens
Trigger: Mounting (doInit) against a Redis metadata URL whose stored format previously had DirStats enabled but the new format disables it (`juicefs config --dir-stats false` or format downgrade), and the Redis transaction DELing the dir-stat keys fails (connection error, READONLY replica, cluster MOVED error, etc.).
Common situations: Pointing at a read-only Redis replica during a format change; Redis cluster topology changes mid-init; network blips between client and Redis while upgrading format settings.
Related errors
- scan trash slices: %s
- remove user group quota
- update format
- database %s is used by volume %s
- load setting: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/bd7dd0f27c9321e1.
Report an issue: GitHub.