juicedata/juicefs · error

only root can restore files from trash

Error message

only root can restore files from trash

What it means

Restoring files from JuiceFS trash manipulates metadata owned by the volume and is restricted to root on POSIX systems. After the Windows-specific elevation check, restore verifies os.Getuid() == 0 and returns this error when a non-root user runs it on Linux/macOS. Note the check is skipped on Windows, where the elevation check above applies instead.

Source

Thrown at cmd/restore.go:50

				Name:  "put-back",
				Usage: "move the recovered files into original directory",
			},
			&cli.IntFlag{
				Name:  "threads",
				Value: 10,
				Usage: "number of threads",
			},
		},
	}
}

func restore(ctx *cli.Context) error {
	setup0(ctx, 2, 0)
	if runtime.GOOS == "windows" && !utils.IsWinAdminOrElevatedPrivilege() {
		return fmt.Errorf("restore command requires Administrator or elevated privilege on Windows")
	}
	if os.Getuid() != 0 && runtime.GOOS != "windows" {
		return fmt.Errorf("only root can restore files from trash")
	}
	removePassword(ctx.Args().Get(0))
	m := meta.NewClient(ctx.Args().Get(0), nil)
	_, err := m.Load(true)
	if err != nil {
		return err
	}
	for i := 1; i < ctx.NArg(); i++ {
		hour := ctx.Args().Get(i)
		doRestore(m, hour, ctx.Bool("put-back"), ctx.Int("threads"))
	}
	return nil
}

func doRestore(m meta.Meta, hour string, putBack bool, threads int) {
	if err := m.NewSession(false); err != nil {
		logger.Warningf("running without sessions because fail to new session: %s", err)
	} else {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Re-run the command with sudo: sudo juicefs restore <meta-url> ...
  2. If in a container, start it as root (--user 0 / run as root entrypoint).
  3. Delegate the restore to an administrator who has root on the client machine.
  4. On Windows clients, use the Windows-elevated path instead (Administrator privilege check).

Example fix

// before
juicefs restore sqlite3:///etc/juicefs/test.db 100
// after
sudo juicefs restore sqlite3:///etc/juicefs/test.db 100
Defensive patterns

Strategy: validation

Validate before calling

# shell pre-check before invoking restore
[ "$(id -u)" -eq 0 ] || { echo "restore must run as root"; exit 1; }

Try / catch

cmd := exec.Command("juicefs", "restore", metaURL, target)
if err := cmd.Run(); err != nil && strings.Contains(err.Error(), "only root can restore") {
    // retry under sudo: exec.Command("sudo", "juicefs", "restore", ...)
}

Prevention

When it happens

Trigger: Running `juicefs restore <meta-url> <inode|name>` as a non-root user on Linux or macOS; the condition os.Getuid() != 0 && runtime.GOOS != "windows" evaluates true.

Common situations: Running restore via sudo-less automation or a service account; container environments where the entrypoint user is non-root; operators accustomed to other JuiceFS commands (like info) that do not require root.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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