{"record":{"id":"79515a3838088d6a","repo":"juicedata/juicefs","slug":"remove-user-group-quota","errorCode":null,"errorMessage":"remove user group quota","messagePattern":"remove user group quota","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/redis.go","lineNumber":367,"sourceCode":"\t\t\t_, err := m.rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {\n\t\t\t\tpipe.Del(ctx, m.dirUsedInodesKey(), m.dirUsedSpaceKey())\n\t\t\t\tm.genLog(ctx, pipe, time.Now(), \"INIT_ENABLE_DIRSTATS()\")\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"remove dir stats\")\n\t\t\t}\n\t\t}\n\t\tif !old.UserGroupQuota && format.UserGroupQuota {\n\t\t\t// remove user group quota as they are outdated\n\t\t\t_, err := m.rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {\n\t\t\t\tpipe.Del(ctx, m.userQuotaKey(), m.userQuotaUsedSpaceKey(), m.userQuotaUsedInodesKey(),\n\t\t\t\t\tm.groupQuotaKey(), m.groupQuotaUsedSpaceKey(), m.groupQuotaUsedInodesKey())\n\t\t\t\tm.genLog(ctx, pipe, time.Now(), \"INIT_ENABLE_USERGROUPQUOTA()\")\n\t\t\t\treturn nil\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrap(err, \"remove user group quota\")\n\t\t\t}\n\t\t}\n\t\tif err = format.update(&old, force); err != nil {\n\t\t\treturn errors.Wrap(err, \"update format\")\n\t\t}\n\t}\n\n\tdata, err := json.MarshalIndent(format, \"\", \"\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"json: %s\", err)\n\t}\n\tts := time.Now().Unix()\n\tattr := &Attr{\n\t\tTyp:    TypeDirectory,\n\t\tAtime:  ts,\n\t\tMtime:  ts,\n\t\tCtime:  ts,\n\t\tNlink:  2,","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/redis.go#L349-L385","documentation":"Returned from redisMeta.doInit when the upgrade path disables UserGroupQuota and the Redis transaction deleting the user/group quota keys fails. JuiceFS removes outdated user and group quota counters (userQuotaKey, groupQuotaKey and their usage keys) whenever the new format turns this feature off; failure aborts mount initialization.","triggerScenarios":"Mounting after `juicefs config --user-group-quota false` (format switched from UserGroupQuota=true to false) when the TxPipelined DEL of the six user/group quota keys fails — Redis unreachable, read-only instance, or cluster routing error.","commonSituations":"Downgrading/disabling user-group quotas in a mixed-version cluster; Redis replica promoted incorrectly as read-only; maxmemory limiting writes during init.","solutions":["Retry the mount after confirming Redis is writable and reachable.","Ensure all old clients have exited before toggling user-group-quota, then re-run the config/mount so key cleanup completes.","Check Redis cluster mode: use the primary node and correct MOVED handling.","If keys are stale but harmless, verify the format was persisted and quota accounting keys will be rebuilt."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Ensure all clients support user-group-quota toggling and Redis is writable:\nif err := rdb.Ping(ctx).Err(); err != nil { return err }\n// run `juicefs config --user-group-quota false` only when old clients exited","typeGuard":null,"tryCatchPattern":"if err := doInit(ctx, format); err != nil {\n    if strings.Contains(err.Error(), \"remove user group quota\") {\n        time.Sleep(backoff); return doInit(ctx, format)\n    }\n    return err\n}","preventionTips":["Drain old clients before toggling user-group-quota in the format.","Always target the writable Redis primary for mounts performing format upgrades.","Verify key cleanup completed with `juicefs status` after config changes.","Test format changes on a staging Redis instance first."],"tags":["go","redis","metadata","quota"],"backgroundTag":"database-write-failed","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"}