juicedata/juicefs · error

invalid quota value: %v

Error message

invalid quota value: %v

What it means

Returned by getQuota (redis.go:4433) when the Redis key holding a quota's configured limits (MaxSpace/MaxInodes, stored as a 16-byte packed binary value via formatQuota) does not decode to exactly 16 bytes. This means the quota record in Redis is corrupted, truncated, or was written by an incompatible client version. The raw buffer is included in the message for diagnosis.

Source

Thrown at pkg/meta/redis.go:4433

		return nil, err
	}

	field := strconv.FormatUint(key, 10)
	cmds, err := m.rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {
		pipe.HGet(ctx, config.quotaKey, field)
		pipe.HGet(ctx, config.usedSpaceKey, field)
		pipe.HGet(ctx, config.usedInodesKey, field)
		return nil
	})
	if err == redis.Nil {
		return nil, nil
	} else if err != nil {
		return nil, err
	}

	buf, _ := cmds[0].(*redis.StringCmd).Bytes()
	if len(buf) != 16 {
		return nil, fmt.Errorf("invalid quota value: %v", buf)
	}

	var quota Quota
	quota.MaxSpace, quota.MaxInodes = m.parseQuota(buf)
	if quota.UsedSpace, err = cmds[1].(*redis.StringCmd).Int64(); err != nil {
		return nil, err
	}
	if quota.UsedInodes, err = cmds[2].(*redis.StringCmd).Int64(); err != nil {
		return nil, err
	}
	return &quota, nil
}

func (m *redisMeta) doSetQuota(ctx Context, qtype uint32, key uint64, quota *Quota) (bool, error) {
	config, err := m.getQuotaKeys(qtype)
	if err != nil {
		return false, err
	}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Inspect the offending key with redis-cli and delete/correct the malformed quota record, then re-set the quota with `juicefs quota set`.
  2. Check client versions: if old clients wrote the quota, upgrade or re-set the quota so it is stored in the current 16-byte packed format.
  3. Verify disk/memory integrity of the Redis instance (AOF/RDB corruption) and restore from a known-good metadata backup.
  4. Run `juicefs gc` / fsck-style tooling to detect and clean inconsistent quota records.

Example fix

// before: quota value written ad-hoc
HSET quotaKey <ino> "1048576"
// after: set quota through the CLI so it is packed correctly
juicefs quota set META-URL --inode 100 --capacity 1073741824
Defensive patterns

Strategy: try-catch

Validate before calling

// verify quota record length before use
buf, _ := redis.StringCmd.Bytes()
if len(buf) != 16 { /* re-set the quota via juicefs quota set before proceeding */ }

Type guard

func validQuotaBuf(b []byte) bool { return len(b) == 16 }

Try / catch

quota, err := meta.LoadQuota(ctx, ino)
if err != nil {
    if strings.Contains(err.Error(), "invalid quota value") {
        // repair: delete malformed record, re-set quota, retry once
    }
    return err
}

Prevention

When it happens

Trigger: Calling loadQuota/getQuota for an inode whose quota hash value in Redis is missing, empty, or not the 16-byte packing produced by parseQuota's counterpart (e.g. after a partial write, manual redis-cli editing, or a dump/load from an older format).

Common situations: Manual manipulation of quota keys in Redis; restore of a metadata backup that predates the packed-quota binary format; data corruption in the Redis instance; mixed-version clusters where an older client wrote a different quota encoding.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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