juicedata/juicefs · error

delete user group quota

Error message

delete user group quota

What it means

In kvMeta.doInit (pkg/meta/tkv.go:553), when the format update enables UserGroupQuota, outdated user/group quota keys (prefixes "QU"/"QG") are deleted in a write transaction; failure is wrapped as "delete user group quota". This cleanup exists because quota records from before the feature flag are considered stale.

Solutions

  1. Retry the format command once the KV cluster is healthy; the cleanup only runs on the false→true transition.
  2. If TiKV reports transaction too large, delete stale QU/QG keys in batches or upgrade to a JuiceFS version handling the cleanup incrementally.
  3. Check backend writability (etcd disk limits, Badger dir permissions, FDB cluster status) based on the wrapped error.
Defensive patterns

Strategy: retry

Validate before calling

null

Try / catch

if err := formatVolume(); err != nil {
    if strings.Contains(err.Error(), "delete user group quota") {
        // inspect wrapped store error; verify writability and retry
    }
}

Prevention

When it happens

Trigger: Running `juicefs format` (or a mount that updates the format) with --enable-user-group-quota on a KV-engine volume where old.UserGroupQuota was false, and the delete transaction fails (store unavailable, transaction too large, write conflict).

Common situations: First-time enablement of user/group quotas on large TiKV/etcd volumes with many leftover quota keys; KV backend in read-only or degraded state; concurrent format operations.

Related errors


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

Appendix: source

Thrown at pkg/meta/tkv.go:553

				m.genLog(tx, time.Now(), "INIT_ENABLE_DIRSTATS()")
				return nil
			})
			if err != nil {
				return errors.Wrap(err, "delete dir stats")
			}
		}
		if !old.UserGroupQuota && format.UserGroupQuota {
			// remove user group quota as they are outdated
			userPrefix := m.fmtKey("QU")
			groupPrefix := m.fmtKey("QG")
			err := m.txn(Background(), func(tx *kvTxn) error {
				tx.deleteKeys(userPrefix)
				tx.deleteKeys(groupPrefix)
				m.genLog(tx, time.Now(), "INIT_ENABLE_USERGROUPQUOTA()")
				return nil
			})
			if err != nil {
				return errors.Wrap(err, "delete user group quota")
			}
		}
		if err = format.update(&old, force); err != nil {
			return errors.Wrap(err, "update format")
		}
	}

	data, err := json.MarshalIndent(format, "", "")
	if err != nil {
		return fmt.Errorf("json: %s", err)
	}

	m.setFormat(format)
	ts := time.Now().Unix()
	attr := &Attr{
		Typ:    TypeDirectory,
		Atime:  ts,
		Mtime:  ts,

View on GitHub (pinned to c9a67b23e8)