juicedata/juicefs · error

failed to read config

Error message

failed to read config

What it means

Wraps an error from readConfig(mp) when `juicefs umount --flush` reads the JuiceFS volume config from the mount point. Unlike the ENOENT case (which reports 'not a JuiceFS mount point'), this fires for all other read failures — permission problems, I/O errors, or malformed mountpoint access.

Source

Thrown at cmd/umount.go:109

		return fmt.Errorf("OS %s is not supported", runtime.GOOS)
	}
	out, err := cmd.CombinedOutput()
	if err != nil && len(out) != 0 {
		err = errors.New(string(out))
	}
	return err
}

func umount(ctx *cli.Context) error {
	setup(ctx, 1)
	mp := ctx.Args().Get(0)
	if ctx.Bool("flush") {
		raw, err := readConfig(mp)
		if err != nil {
			if os.IsNotExist(err) {
				return fmt.Errorf("not a JuiceFS mount point")
			}
			return errors.Wrap(err, "failed to read config")
		}

		var conf vfs.Config
		if err = json.Unmarshal(raw, &conf); err != nil {
			return errors.Wrap(err, "failed to parse config")
		}
		if conf.Chunk.Writeback {
			stagingDir := path.Join(conf.Chunk.CacheDir, "rawstaging")
			if err := waitWritebackComplete(stagingDir); err != nil {
				return err
			}
			defer func() {
				size, _ := fileSizeInDir(stagingDir)
				clearLastLine()
				if size == 0 {
					fmt.Println("\rAll staging chunks are flushed")
				} else {
					fmt.Printf("\r%s staging chunks are not flushed\n", humanize.IBytes(size))

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Read the full wrapped cause to identify the underlying errno (EACCES vs EIO vs ESTALE)
  2. Check the mount is alive: `mountpoint <mp>` and `ls <mp>`; if hung, use `juicefs umount --force <mp>` (without --flush)
  3. Retry with sufficient permissions (root/sudo) if it is an access error
  4. If the FUSE connection is dead, force-unmount (`fusermount -uz <mp>`) and remount

Example fix

// before
juicefs umount /mnt/jfs --flush        # hangs / EIO, dead mount
// after
sudo umount -l /mnt/jfs                # or fusermount -uz /mnt/jfs, then remount
sudo juicefs umount /mnt/jfs --flush   # retry flush with proper permissions on healthy mount
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(mp); err != nil { return fmt.Errorf("mountpoint missing: %w", err) }
if out, err := exec.Command("mountpoint", mp).CombinedOutput(); err != nil { return fmt.Errorf("not a mountpoint: %s", out) }

Try / catch

if err := umountCmd(mp, true); err != nil {
	var perr *fs.PathError
	if errors.As(err, &perr) && errors.Is(err, syscall.EIO) { /* dead mount: force unmount */ }
}

Prevention

When it happens

Trigger: Running `juicefs umount <mp> --flush` where reading `.config` (or the config access path) inside the mountpoint fails with an error other than NotExist: no read permission on the mountpoint, stale/hung FUSE mount returning EIO/EACCES, network filesystem shadowing, or the mount process crashed leaving a broken mount.

Common situations: Unmounting a FUSE mountpoint whose juicefs process has died (mountpoint hangs, I/O errors); running as a user without permission to traverse the mountpoint; NFS/other fs mounted at the same path; dying metadata connection making any read on the mount fail.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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