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
- Read the full wrapped cause to identify the underlying errno (EACCES vs EIO vs ESTALE)
- Check the mount is alive: `mountpoint <mp>` and `ls <mp>`; if hung, use `juicefs umount --force <mp>` (without --flush)
- Retry with sufficient permissions (root/sudo) if it is an access error
- 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
- Verify the mountpoint is alive (`ls <mp>`) before umount --flush
- Keep the juicefs mount process healthy; use --force only as last resort
- Run umount with root or the mounting user's permissions
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.