{"record":{"id":"6dfc9c634927a580","repo":"juicedata/juicefs","slug":"set-tier-for-inode-d-tier-d-failed-w","errorCode":null,"errorMessage":"set tier for inode %d tier:%d failed: %w","messagePattern":"set tier for inode (.+?) tier:(.+?) failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/tier.go","lineNumber":208,"sourceCode":"\t}\n\tcheckFunc := func(ino meta.Ino, oriTier uint8) bool {\n\t\tif id == uint(oriTier) && !ctx.Bool(\"force\") {\n\t\t\tlogger.Debugf(\"inode:%d storage tier is already %d, no change needed\", ino, oriTier)\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\tswitch attr.Typ {\n\tcase meta.TypeFile:\n\t\terr = visitEntry(m, format, ino, attr, objectFunc, metaFunc, checkFunc)\n\tcase meta.TypeDirectory:\n\t\tif ctx.Bool(\"recursive\") {\n\t\t\tif err = visitDir(m, format, ino, ctx.Bool(\"recursive\"), objectFunc, metaFunc, checkFunc); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err = metaFunc(ino); err != nil {\n\t\t\treturn fmt.Errorf(\"set tier for inode %d tier:%d failed: %w\", ino, newTier.ID, err)\n\t\t}\n\n\tdefault:\n\t\tlogger.Fatal(\"only file and directory are supported to set storage tier\")\n\t}\n\treturn err\n}\n\nfunc objRestore(ctx *cli.Context) error {\n\tsetup(ctx, 2)\n\tremovePassword(ctx.Args().Get(0))\n\tpath := ctx.Args().Get(1)\n\tdays := ctx.Int(\"days\")\n\tm := meta.NewClient(ctx.Args().Get(0), nil)\n\tformat, err := m.Load(true)\n\tif err != nil {\n\t\tlogger.Fatalf(\"load setting: %s\", err)\n\t}","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/tier.go#L190-L226","documentation":"In setTier, after processing the target inode's objects, the command applies the tier change at the metadata level via metaFunc(ino). If that metadata call fails, the error is wrapped with the inode and the new tier's ID so the user knows exactly which file and target tier failed. The underlying cause (the %w-wrapped error) typically comes from the metadata engine (e.g. SetXattr/updateTier failing).","triggerScenarios":"`juicefs tier` targeting a single (non-recursive) path whose inode's tier update fails in the metadata engine — e.g. connection loss to Redis/SQL metadata, xattr rejection, or permission issues.","commonSituations":"Metadata engine unreachable mid-operation; inode deleted by another client between listing and tier update; storage class/tier not configured on the volume; SELinux or permission problems on the FUSE mount.","solutions":["Read the wrapped cause after 'failed:' to see the metadata engine error.","Verify the volume has the target storage class/tier configured (juicefs config).","Check connectivity to the metadata engine and retry the command.","Confirm the inode still exists (file may have been deleted concurrently)."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if _, err := os.Stat(path); err != nil {\n    return fmt.Errorf(\"path gone before tier set: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := juicefsTier(path, tier); err != nil {\n    var transient = isTransientMetaErr(err)\n    if transient { backoff(retries); continue }\n    return err\n}","preventionTips":["Check metadata engine connectivity before bulk tier operations","Configure the target storage class on the volume before setting tiers","Avoid concurrent delete/rename of files being tiered"],"tags":["tier","metadata","cli"],"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"}