juicedata/juicefs · error

invalid quota type: %d

Error message

invalid quota type: %d

What it means

Returned by cleanUgUsage (redis.go:4618) when the qtype argument is neither UserQuotaType nor GroupQuotaType. cleanUgUsage clears per-user/per-group used-usage hashes, so only those two quota types are valid; passing any other value (0, DirQuotaType, arbitrary integers) is rejected before any Redis keys are touched.

Source

Thrown at pkg/meta/redis.go:4618

		for _, q := range quotas {
			config, err := m.getQuotaKeys(q.qtype)
			if err != nil {
				return err
			}

			key := strconv.FormatUint(q.qkey, 10)
			pipe.HSetNX(ctx, config.quotaKey, key, m.packQuota(-1, -1))
			pipe.HIncrBy(ctx, config.usedSpaceKey, key, q.quota.newSpace)
			pipe.HIncrBy(ctx, config.usedInodesKey, key, q.quota.newInodes)
		}
		return nil
	})
	return err
}

func (m *redisMeta) cleanUgUsage(ctx Context, qtype uint32) error {
	if qtype != UserQuotaType && qtype != GroupQuotaType {
		return fmt.Errorf("invalid quota type: %d", qtype)
	}
	config, err := m.getQuotaKeys(qtype)
	if err != nil {
		return err
	}
	return m.hscan(ctx, config.quotaKey, func(keys []string) error {
		_, err := m.rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
			for i := 0; i < len(keys); i += 2 {
				key := keys[i]
				pipe.HSet(ctx, config.usedSpaceKey, key, 0)
				pipe.HSet(ctx, config.usedInodesKey, key, 0)
			}
			return nil
		})
		return err
	})
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Pass the correct constant: meta.UserQuotaType or meta.GroupQuotaType, depending on which usage you intend to clean.
  2. If you meant to clean directory quota usage, use the directory-quota cleanup path instead of cleanUgUsage.
  3. Verify the caller's qtype variable is initialized (a zero-value uint32 will fail this check).

Example fix

// before
err = m.cleanUgUsage(ctx, DirQuotaType)
// after
err = m.cleanUgUsage(ctx, UserQuotaType) // or GroupQuotaType
Defensive patterns

Strategy: validation

Validate before calling

if qtype != meta.UserQuotaType && qtype != meta.GroupQuotaType {
    return fmt.Errorf("cleanUgUsage requires UserQuotaType or GroupQuotaType, got %d", qtype)
}

Type guard

func isUgQuotaType(t uint32) bool { return t == meta.UserQuotaType || t == meta.GroupQuotaType }

Try / catch

if err := m.cleanUgUsage(ctx, qtype); err != nil {
    if strings.Contains(err.Error(), "invalid quota type") {
        // caller bug: check the constant passed
    }
    return err
}

Prevention

When it happens

Trigger: Calling cleanUgUsage (or the internal paths that dispatch to it) with a qtype value other than UserQuotaType/GroupQuotaType — e.g. passing DirQuotaType to a user/group cleanup routine, or an uninitialized/zero uint32.

Common situations: Custom tooling calling internal meta APIs with the wrong quota-type constant; a code path confusing directory quotas (which have their own cleanup) with user/group quotas; uninitialized variable in a patch.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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