juicedata/juicefs · error
write message: %s
Error message
write message: %s
What it means
JuiceFS clone works by writing a serialized Clone control message to the control file (.control) exposed by the FUSE mount at the SRC mount point. If the write to that control pipe fails, the command reports "write message: %s" with the underlying error — typically a broken pipe, ENOSPC/EDQUOT, or I/O error on the mount.
Source
Thrown at cmd/clone.go:145
contentSize := 8 + 8 + 8 + 1 + uint32(len(dstName)) + 2 + 1 + 1 // +1 for threads
wb := utils.NewBuffer(uint32(headerSize) + contentSize)
wb.Put32(meta.Clone)
wb.Put32(contentSize)
wb.Put64(srcIno)
wb.Put64(srcParentIno)
wb.Put64(dstParentIno)
wb.Put8(uint8(len(dstName)))
wb.Put([]byte(dstName))
wb.Put16(uint16(umask))
wb.Put8(cmode)
wb.Put8(uint8(threads))
f, err := openController(srcMp)
if err != nil {
return err
}
defer f.Close()
if _, err = f.Write(wb.Bytes()); err != nil {
return fmt.Errorf("write message: %s", err)
}
progress := utils.NewProgress(false)
defer progress.Done()
bar := progress.AddCountBar("Cloning entries", 0)
if _, errno := readProgress(f, func(count uint64, total uint64) {
bar.SetTotal(int64(total))
bar.SetCurrent(int64(count))
}); errno != 0 {
return fmt.Errorf("clone failed: %v", errno)
}
return nil
}
func findMountpoint(fpath string) (string, error) {
for p := fpath; p != "/"; p = filepath.Dir(p) {
inode, err := utils.GetFileInode(p)
if err != nil {View on GitHub (pinned to c9a67b23e8)
Solutions
- Check the mount is alive: `juicefs status META-URL` and `ls /mnt/jfs/.control`; if dead, remount with `juicefs mount`
- Inspect kernel logs (`dmesg | grep -i fuse`) for a FUSE abort and remount after fixing the cause
- Retry the clone once the mount is healthy — the operation is not partially applied if the message never reached the daemon
- Avoid autofs idle unmounts during long operations (raise the autofs timeout)
Example fix
# before (mount crashed) juicefs clone /mnt/jfs/a /mnt/jfs/b # write message: broken pipe // after juicefs mount redis://127.0.0.1:6379/1 /mnt/jfs juicefs clone /mnt/jfs/a /mnt/jfs/b
Defensive patterns
Strategy: retry
Validate before calling
if _, err := os.Stat(filepath.Join(mountpoint, ".control")); err != nil {
return fmt.Errorf("mount at %s is not serving control file: %w", mountpoint, err)
} Try / catch
err := runClone(src, dst)
if err != nil && (strings.Contains(err.Error(), "broken pipe") || strings.Contains(err.Error(), "transport endpoint")) {
remount(mountpoint)
err = runClone(src, dst)
} Prevention
- Check mount health (ls the mountpoint) before long-running operations
- Monitor the mount daemon for crashes/OOM
- Disable aggressive autofs idle unmounts during batch jobs
- Watch `dmesg` for FUSE aborts in flaky environments
When it happens
Trigger: Running `juicefs clone` when the FUSE mount has just unmounted or crashed (broken pipe / transport endpoint not connected); the control file write fails due to disk/memory pressure; the mount process was killed between openController and the Write.
Common situations: Mount daemon restarted or crashed mid-command; volume unmounted by autofs idle timeout; FUSE connection aborted (dmesg shows fuse issues); running clone against a mount whose daemon was OOM-killed.
Related errors
- open control file for [%d:%s]: %w
- clone failed: %v
- open control file for %s: %s
- read device list file
- Unable to skip %s bytes (position=%s, fileSize=%s): %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/dd17c65e9a08973f.
Report an issue: GitHub.