juicedata/juicefs · error

failed to load %s quotas: %w

Error message

failed to load %s quotas: %w

What it means

Wrapped error from loadQuotas (redis.go:4541). While loading all user/group (or dir) quotas, the call to getQuotaKeys for a quota type failed, and the underlying error is wrapped as "failed to load %s quotas". getQuotaKeys itself returns an error only when the quota type is unknown/unsupported, so this almost always indicates an internal inconsistency rather than bad user input.

Source

Thrown at pkg/meta/redis.go:4541

	quotaTypes := []struct {
		enabled bool
		qtype   uint32
		name    string
		quotas  map[uint64]*Quota
	}{
		{format.DirStats, DirQuotaType, "dir", dirQuotas},
		{format.UserGroupQuota, UserQuotaType, "user", userQuotas},
		{format.UserGroupQuota, GroupQuotaType, "group", groupQuotas},
	}

	for _, qt := range quotaTypes {
		if !qt.enabled {
			continue
		}

		config, err := m.getQuotaKeys(qt.qtype)
		if err != nil {
			return nil, nil, nil, fmt.Errorf("failed to load %s quotas: %w", qt.name, err)
		}

		usedInodesMap, err := m.hscanToMap(ctx, config.usedInodesKey)
		if err != nil {
			return nil, nil, nil, err
		}
		usedSpaceMap, err := m.hscanToMap(ctx, config.usedSpaceKey)
		if err != nil {
			return nil, nil, nil, err
		}
		quotaMap, err := m.hscanToMap(ctx, config.quotaKey)
		if err != nil {
			return nil, nil, nil, err
		}

		for key, usedInodesStr := range usedInodesMap {
			id, err := strconv.ParseUint(key, 10, 64)
			if err != nil {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Read the wrapped inner error (%w) to see why getQuotaKeys failed and fix the root cause.
  2. If you patched the code and added a quota type to the enabled list, add the corresponding case in getQuotaKeys.
  3. Ensure all clients mounting the volume are the same version so the quota-type table is consistent.
  4. Restart with a stock JuiceFS build to rule out a local modification causing the mismatch.

Example fix

// before
// enabled: DirQuotaType, UserQuotaType, NewCustomType // getQuotaKeys has no case
// after
// add case NewCustomType in getQuotaKeys, or remove it from the enabled list
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure every enabled quota type has a getQuotaKeys mapping before starting
for _, qt := range enabledQuotas {
    if _, err := m.getQuotaKeys(qt.qtype); err != nil { return err }
}

Type guard

func supportedQuotaType(t uint32) bool { return t == UserQuotaType || t == GroupQuotaType || t == DirQuotaType }

Try / catch

quotas, used, pending, err := m.loadQuotas(ctx)
if err != nil {
    var wrapped interface{ Unwrap() error }
    if errors.As(err, &inner) { log.Printf("quota key lookup failed: %v", inner) }
    return err
}

Prevention

When it happens

Trigger: Calling loadQuotas (quota listing/sync path) when m.getQuotaKeys(qt.qtype) returns an error for an enabled quota type in the qtype list.

Common situations: A new quota type was enabled in the enabledQuotas list but getQuotaKeys was not extended to return key names for it; mixed-version client code where a newer client enumerates a quota type the loaded code does not map.

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/7f9f8059d970c183. Report an issue: GitHub.