{"record":{"id":"fcc408864facc48d","repo":"juicedata/juicefs","slug":"invalid-key-x","errorCode":null,"errorMessage":"invalid key %x","messagePattern":"invalid key %x","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/meta/tkv.go","lineNumber":3360,"sourceCode":"\t\t}\n\t\treturn true\n\t})\n}\n\nfunc (m *kvMeta) scanPendingFiles(ctx Context, scan pendingFileScan) error {\n\tif scan == nil {\n\t\treturn nil\n\t}\n\t// deleted files: Diiiiiiiissssssss\n\tklen := 1 + 8 + 8\n\n\tvar scanErr error\n\tif err := m.client.scan(m.fmtKey(\"D\"), func(key, val []byte) bool {\n\t\tif scanErr != nil {\n\t\t\treturn true\n\t\t}\n\t\tif len(key) != klen {\n\t\t\tscanErr = fmt.Errorf(\"invalid key %x\", key)\n\t\t\treturn true\n\t\t}\n\t\tino := m.decodeInode(key[1:9])\n\t\tsize := binary.BigEndian.Uint64(key[9:])\n\t\tts := m.parseInt64(val)\n\t\t_, scanErr = scan(ino, size, ts)\n\t\treturn true\n\t}); err != nil {\n\t\treturn err\n\t}\n\n\treturn scanErr\n}\n\nfunc (m *kvMeta) doRepair(ctx Context, inode Ino, attr *Attr) syscall.Errno {\n\tprefix := m.entryKey(inode, \"\")\n\treturn errno(m.txn(ctx, func(tx *kvTxn) error {\n\t\tattr.Nlink = 2","sourceCodeStart":3342,"sourceCodeEnd":3378,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/meta/tkv.go#L3342-L3378","documentation":"During a full scan of the 'D' (deleted-file/trash size) key space, kvMeta expects every key to be exactly 17 bytes (1-byte prefix + 8-byte inode + 8-byte size). A key of any other length is treated as corrupt and the scan aborts with this error, propagated as scanErr.","triggerScenarios":"Calling trash/deleted-size listing (e.g. juicefs info/gc or trash scan) against a TKV engine where the 'D'-prefixed key space contains a malformed or foreign key (manual writes, restored data, version mismatch).","commonSituations":"Restoring a TiKV/etcd namespace from a partial backup that truncated keys; another application sharing the KV namespace wrote keys under the 'D' prefix; dump/load migration artifacts.","solutions":["Inspect the 'D'-prefix keys in the metadata store and remove/repair keys that are not 17 bytes long (prefix + 16 bytes payload)","Restore metadata from a consistent 'juicefs dump' backup","Ensure no other applications share the same KV namespace/prefix as the JuiceFS volume","Upgrade all clients to the same JuiceFS version so key encodings match"],"exampleFix":"// before (scan aborts on first bad key)\nif len(key) != klen {\n\tscanErr = fmt.Errorf(\"invalid key %x\", key)\n\treturn true\n}\n// after (skip and continue)\nif len(key) != klen {\n\tlogger.Warnf(\"skip invalid key %x during scan\", key)\n\treturn false\n}","handlingStrategy":"try-catch","validationCode":"// ensure metadata store namespace is dedicated and consistent\njuicefs fsck <meta-url>  // run before scanning trash/gc","typeGuard":null,"tryCatchPattern":"if err := scanTrash(); err != nil {\n\tvar expected = \"invalid key\"\n\tif strings.Contains(err.Error(), expected) {\n\t\t// inspect D-prefix keys in the store; restore from dump backup\n\t}\n}","preventionTips":["Keep the KV namespace exclusive to one JuiceFS volume","Restore metadata only from complete, consistent dumps","Keep all clients on the same JuiceFS version","Verify key lengths after manual KV maintenance"],"tags":["metadata","kv-store","scan","corruption"],"backgroundTag":"schema-validation-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"}