{"record":{"id":"fbaa2e7c60d15f32","repo":"juicedata/juicefs","slug":"failed-to-load-q-quotas-w","errorCode":null,"errorMessage":"failed to load %q quotas: %w","messagePattern":"failed to load %q quotas: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/tkv.go","lineNumber":3603,"sourceCode":"\tquotaTypes := []struct {\n\t\tenabled bool\n\t\tprefix  string\n\t\tname    string\n\t\tquotas  map[uint64]*Quota\n\t\tdecode  func(k string) uint64\n\t}{\n\t\t{format.DirStats, \"QD\", \"dir\", dirQuotas, func(k string) uint64 { return uint64(m.decodeInode([]byte(k[2:]))) }}, // skip prefix\n\t\t{format.UserGroupQuota, \"QU\", \"user\", userQuotas, func(k string) uint64 { return binary.BigEndian.Uint64([]byte(k[2:])) }},\n\t\t{format.UserGroupQuota, \"QG\", \"group\", groupQuotas, func(k string) uint64 { return binary.BigEndian.Uint64([]byte(k[2:])) }},\n\t}\n\n\tfor _, qt := range quotaTypes {\n\t\tif !qt.enabled {\n\t\t\tcontinue\n\t\t}\n\t\tpairs, err := m.scanValues(ctx, m.fmtKey(qt.prefix), -1, nil)\n\t\tif err != nil {\n\t\t\treturn nil, nil, nil, fmt.Errorf(\"failed to load %q quotas: %w\", qt.name, err)\n\t\t}\n\t\tfor k, v := range pairs {\n\t\t\tqt.quotas[qt.decode(k)] = m.parseQuota(v)\n\t\t}\n\t}\n\n\treturn dirQuotas, userQuotas, groupQuotas, nil\n}\n\nfunc (m *kvMeta) cleanUgUsage(ctx Context, qtype uint32) error {\n\tif qtype != UserQuotaType && qtype != GroupQuotaType {\n\t\treturn fmt.Errorf(\"invalid quota type: %d\", qtype)\n\t}\n\n\tvar prefix string\n\tif qtype == UserQuotaType {\n\t\tprefix = \"QU\"\n\t} else {","sourceCodeStart":3585,"sourceCodeEnd":3621,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/tkv.go#L3585-L3621","documentation":"loadQuotas scans all enabled quota key prefixes ('QD','QU','QG') via scanValues; if the underlying KV scan itself fails (connection error, timeout, store error), the raw error is wrapped with the quota category name to show which quota type could not be loaded.","triggerScenarios":"Loading quotas at mount/startup (or during quota usage aggregation) when the TKV client's scan/iterator fails — network partition, store unavailable, prefix too large hitting an iterator limit (etcd's range limit, for example).","commonSituations":"etcd range requests exceeding its response/transaction size limits with many quotas; TiKV/etcd connectivity problems at mount time; store-side timeouts under heavy load.","solutions":["Check connectivity to the metadata engine and retry the mount/load operation","If using etcd with many quotas, reduce quota count or move to a store without iterator limits (Redis/MySQL/TiKV)","Inspect the wrapped inner error (%w) to identify the store-level cause and fix that first","Increase scan/request limits in the KV store configuration (e.g. etcd --max-request-bytes)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// health-check the metadata engine before loading quotas\nif err := pingMetaEngine(metaURL); err != nil {\n\treturn fmt.Errorf(\"metadata engine unreachable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"quotaLoad := func() error { return loadQuotas(ctx) }\nif err := backoff.Retry(quotaLoad, backoff.WithMaxRetries(3)); err != nil {\n\t// inspect wrapped store error: connectivity vs. scan limits\n}","preventionTips":["Keep quota counts modest if using etcd (iterator/range limits)","Monitor metadata engine health before mount/startup","Read the wrapped inner error to target the store-level cause","Prefer stores without scan-size limits for many-quota deployments"],"tags":["quota","scan","kv-store","network"],"backgroundTag":"database-query-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}