juicedata/juicefs · error

failed to stat %s: %s

Error message

failed to stat %s: %s

What it means

When mounting, `handleSysMountArgs` translates legacy/free-form mount options into cmd flags using optionToCmdFlag and cmdFlagsLookup. If an option is known to the command's flag set and is NOT a boolean flag, a value must follow it; when the value is missing (or consumed incorrectly), load aborts with `option <opt> requires a value`.

Source

Thrown at cmd/load.go:124

func open(src string, key string, algo string) (io.ReadCloser, error) {
	var r io.ReadCloser
	var ioErr error
	var fp io.ReadCloser
	if key != "" {
		privKey, err := object.ParsePrivateKeyFromPem([]byte(loadEncrypt(key)), []byte(os.Getenv("JFS_RSA_PASSPHRASE")))
		if err != nil {
			if errors.Is(err, object.ErrKeyNeedPasswd) {
				return nil, fmt.Errorf("%w: please set the 'JFS_RSA_PASSPHRASE' environment variable", err)
			}
			return nil, fmt.Errorf("parse private key: %s", err)
		}
		encryptor, err := object.NewDataEncryptor(object.NewKeyEncryptor(privKey), algo)
		if err != nil {
			return nil, err
		}
		if _, err := os.Stat(src); err != nil {
			return nil, fmt.Errorf("failed to stat %s: %s", src, err)
		}
		var srcAbsPath string
		srcAbsPath, err = filepath.Abs(src)
		if err != nil {
			return nil, fmt.Errorf("failed to get absolute path of %s: %s", src, err)
		}
		fileBlob, err := object.CreateStorage("file", strings.TrimSuffix(src, filepath.Base(srcAbsPath)), "", "", "")
		if err != nil {
			return nil, err
		}
		blob := object.NewEncrypted(fileBlob, encryptor)
		fp, ioErr = blob.Get(context.Background(), filepath.Base(srcAbsPath), 0, -1)
	} else {
		fp, ioErr = os.Open(src)
	}
	if ioErr != nil {
		return nil, ioErr
	}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Supply the value directly after the option: `--attr-cache 1s`
  2. Check the generating script/fstab unit — an unset variable likely produced the empty value; echo the final command to inspect it
  3. Use `juicefs mount --help` to confirm which options take values vs are boolean
  4. Remove the dangling option entirely if you meant the default

Example fix

// before
juicefs mount --attr-cache redis://10.0.0.1/1 /mnt/jfs
// after
juicefs mount --attr-cache 1s redis://10.0.0.1/1 /mnt/jfs
Defensive patterns

Strategy: validation

Validate before calling

if fi, err := os.Stat(backupPath); err != nil || fi.IsDir() {
    return fmt.Errorf("backup %s unavailable: %v", backupPath, err)
}

Try / catch

if err := cmd.Run(); err != nil {
    if strings.Contains(err.Error(), "failed to stat") {
        log.Fatalf("backup path does not exist: %v", err)
    }
}

Prevention

When it happens

Trigger: `juicefs mount` (or mount helper paths from Main / tests) invoked with a value-taking option such as `--attr-cache`, `--entry-cache`, `--dir-entry-cache`, `--metrics`, `--cache-dir`, `--bucket` etc. without its value — e.g. as the last argument, or with the value separated in a way the parser didn't associate (an empty string, or the next token itself looks like an option).

Common situations: systemd/fstab mount unit dropping the last argument; shell scripts building mount args where a variable holding the value is empty; hand-edited fstab entries missing the value after an option; copy-pasted commands where a flag was left dangling.

Understand the failure class

Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.

Related errors


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