{"record":{"id":"b525ae9e34701d13","repo":"juicedata/juicefs","slug":"invalid-key-s-fail-to-parse-id","errorCode":null,"errorMessage":"invalid key %s, fail to parse id","messagePattern":"invalid key (.+?), fail to parse id","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/meta/redis.go","lineNumber":4194,"sourceCode":"\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tif refs < 0 {\n\t\t\t\t\tpendingKeys <- keys[i]\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t\tclose(pendingKeys)\n\t}()\n\n\tfor key := range pendingKeys {\n\t\tps := strings.Split(key[1:], \"_\")\n\t\tif len(ps) != 2 {\n\t\t\treturn fmt.Errorf(\"invalid key %s\", key)\n\t\t}\n\t\tid, err := strconv.ParseUint(ps[0], 10, 64)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"invalid key %s, fail to parse id\", key)\n\t\t}\n\t\tsize, err := strconv.ParseUint(ps[1], 10, 64)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"invalid key %s, fail to parse size\", key)\n\t\t}\n\t\tclean, err := scan(id, uint32(size))\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"scan pending slices\")\n\t\t}\n\t\tif clean {\n\t\t\t// TODO: m.deleteSlice(id, uint32(size))\n\t\t\t// avoid lint warning\n\t\t\t_ = clean\n\t\t}\n\t}\n\treturn nil\n}\n","sourceCodeStart":4176,"sourceCodeEnd":4212,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/redis.go#L4176-L4212","documentation":"Raised while scanning pending (uncommitted) slices stored as Redis keys of the form \"<id>_<size>\" during GC. The key's id portion could not be parsed with strconv.ParseUint, meaning the metadata engine found a pending-slice key that does not follow the expected \"<inode/slice-id>_<size>\" layout — indicating key corruption or unexpected data in the pending-slices keyspace.","triggerScenarios":"Running `juicefs gc` (scanPendingSlices) when a key in the pending-slices keyspace parses into the wrong number of parts (already reported as \"invalid key\") or its id segment is not a valid base-10 uint64.","commonSituations":"Manually written/corrupted keys in Redis; keys left by a different or much older JuiceFS version with a different key format; accidental writes into the JuiceFS keyspace by other tools.","solutions":["Inspect the offending key with redis-cli (the key name is in the message) and delete it if it is not a valid pending slice.","Confirm the Redis DB is exclusively used by JuiceFS (shared databases often accumulate foreign keys).","Check whether the keys were produced by an incompatible JuiceFS version and upgrade/downgrade accordingly.","Re-run `juicefs gc` after cleanup; GC is resumable and idempotent per key."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate pending-slice key format before processing:\nparts := strings.Split(key, \"_\")\nif len(parts) != 2 { /* skip/report foreign key */ }\nif _, err := strconv.ParseUint(parts[0], 10, 64); err != nil { /* corrupt key */ }","typeGuard":"func validPendingSliceKey(key string) bool {\n    ps := strings.Split(strings.TrimPrefix(key, setting.Name+\"\\x00\"), \"_\")\n    if len(ps) != 2 { return false }\n    _, e1 := strconv.ParseUint(ps[0], 10, 64)\n    _, e2 := strconv.ParseUint(ps[1], 10, 64)\n    return e1 == nil && e2 == nil\n}","tryCatchPattern":"if err := gc(); err != nil {\n    var ke *ParseKeyError\n    if stderrors.As(err, &ke) { logger.Warnf(\"skip corrupt key %s\", ke.Key); return nil }\n    return err\n}","preventionTips":["Dedicate the Redis DB to JuiceFS; never share keyspaces with other apps.","Do not manually insert or edit keys in the metadata engine.","Keep all clients on the same JuiceFS major version.","Periodically audit the pending-slices keyspace for foreign keys."],"tags":["go","redis","gc","key-format"],"backgroundTag":"invalid-identifier-format","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"}