juicedata/juicefs · error

set tier for inode %d tier:%d failed: %w

Error message

set tier for inode %d tier:%d failed: %w

What it means

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).

Source

Thrown at cmd/tier.go:208

	}
	checkFunc := func(ino meta.Ino, oriTier uint8) bool {
		if id == uint(oriTier) && !ctx.Bool("force") {
			logger.Debugf("inode:%d storage tier is already %d, no change needed", ino, oriTier)
			return true
		}
		return false
	}
	switch attr.Typ {
	case meta.TypeFile:
		err = visitEntry(m, format, ino, attr, objectFunc, metaFunc, checkFunc)
	case meta.TypeDirectory:
		if ctx.Bool("recursive") {
			if err = visitDir(m, format, ino, ctx.Bool("recursive"), objectFunc, metaFunc, checkFunc); err != nil {
				return err
			}
		}
		if err = metaFunc(ino); err != nil {
			return fmt.Errorf("set tier for inode %d tier:%d failed: %w", ino, newTier.ID, err)
		}

	default:
		logger.Fatal("only file and directory are supported to set storage tier")
	}
	return err
}

func objRestore(ctx *cli.Context) error {
	setup(ctx, 2)
	removePassword(ctx.Args().Get(0))
	path := ctx.Args().Get(1)
	days := ctx.Int("days")
	m := meta.NewClient(ctx.Args().Get(0), nil)
	format, err := m.Load(true)
	if err != nil {
		logger.Fatalf("load setting: %s", err)
	}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Read the wrapped cause after 'failed:' to see the metadata engine error.
  2. Verify the volume has the target storage class/tier configured (juicefs config).
  3. Check connectivity to the metadata engine and retry the command.
  4. Confirm the inode still exists (file may have been deleted concurrently).
Defensive patterns

Strategy: retry

Validate before calling

if _, err := os.Stat(path); err != nil {
    return fmt.Errorf("path gone before tier set: %w", err)
}

Try / catch

if err := juicefsTier(path, tier); err != nil {
    var transient = isTransientMetaErr(err)
    if transient { backoff(retries); continue }
    return err
}

Prevention

When it happens

Trigger: `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.

Common situations: 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.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/6dfc9c634927a580. Report an issue: GitHub.