{"record":{"id":"86610face73d0190","repo":"juicedata/juicefs","slug":"invalid-quota-value-v","errorCode":null,"errorMessage":"invalid quota value: %v","messagePattern":"invalid quota value: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/redis.go","lineNumber":4433,"sourceCode":"\t\treturn nil, err\n\t}\n\n\tfield := strconv.FormatUint(key, 10)\n\tcmds, err := m.rdb.Pipelined(ctx, func(pipe redis.Pipeliner) error {\n\t\tpipe.HGet(ctx, config.quotaKey, field)\n\t\tpipe.HGet(ctx, config.usedSpaceKey, field)\n\t\tpipe.HGet(ctx, config.usedInodesKey, field)\n\t\treturn nil\n\t})\n\tif err == redis.Nil {\n\t\treturn nil, nil\n\t} else if err != nil {\n\t\treturn nil, err\n\t}\n\n\tbuf, _ := cmds[0].(*redis.StringCmd).Bytes()\n\tif len(buf) != 16 {\n\t\treturn nil, fmt.Errorf(\"invalid quota value: %v\", buf)\n\t}\n\n\tvar quota Quota\n\tquota.MaxSpace, quota.MaxInodes = m.parseQuota(buf)\n\tif quota.UsedSpace, err = cmds[1].(*redis.StringCmd).Int64(); err != nil {\n\t\treturn nil, err\n\t}\n\tif quota.UsedInodes, err = cmds[2].(*redis.StringCmd).Int64(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &quota, nil\n}\n\nfunc (m *redisMeta) doSetQuota(ctx Context, qtype uint32, key uint64, quota *Quota) (bool, error) {\n\tconfig, err := m.getQuotaKeys(qtype)\n\tif err != nil {\n\t\treturn false, err\n\t}","sourceCodeStart":4415,"sourceCodeEnd":4451,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/redis.go#L4415-L4451","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Inspect the offending key with redis-cli and delete/correct the malformed quota record, then re-set the quota with `juicefs quota set`.","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.","Verify disk/memory integrity of the Redis instance (AOF/RDB corruption) and restore from a known-good metadata backup.","Run `juicefs gc` / fsck-style tooling to detect and clean inconsistent quota records."],"exampleFix":"// before: quota value written ad-hoc\nHSET quotaKey <ino> \"1048576\"\n// after: set quota through the CLI so it is packed correctly\njuicefs quota set META-URL --inode 100 --capacity 1073741824","handlingStrategy":"try-catch","validationCode":"// verify quota record length before use\nbuf, _ := redis.StringCmd.Bytes()\nif len(buf) != 16 { /* re-set the quota via juicefs quota set before proceeding */ }","typeGuard":"func validQuotaBuf(b []byte) bool { return len(b) == 16 }","tryCatchPattern":"quota, err := meta.LoadQuota(ctx, ino)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid quota value\") {\n        // repair: delete malformed record, re-set quota, retry once\n    }\n    return err\n}","preventionTips":["Always set quotas through `juicefs quota set`, never by writing raw Redis hashes.","Keep all client versions identical when quota features are in use.","Monitor Redis persistence health (AOF rewrite errors, RDB save failures).","Periodically verify quota consistency after any dump/load restore."],"tags":["redis","quota","metadata","data-corruption"],"backgroundTag":"invalid-argument-format","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}