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

  1. Retry the mount once Redis connectivity is restored; doInit re-runs the removal transaction.
  2. Verify the Redis instance is writable (not a READONLY replica) and that the key exists on the primary in cluster mode.
  3. Check Redis logs for OOM or maxmemory errors blocking writes.
  4. 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

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


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