{"record":{"id":"1b2d69b8c19667ea","repo":"juicedata/juicefs","slug":"failed-to-read-staging-directory","errorCode":null,"errorMessage":"failed to read staging directory","messagePattern":"failed to read staging directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/umount.go","lineNumber":143,"sourceCode":"\t\t\t\t\tfmt.Println(\"\\rAll staging chunks are flushed\")\n\t\t\t\t} else {\n\t\t\t\t\tfmt.Printf(\"\\r%s staging chunks are not flushed\\n\", humanize.IBytes(size))\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t}\n\treturn doUmount(mp, ctx.Bool(\"force\"))\n}\n\nfunc waitWritebackComplete(stagingDir string) error {\n\tlastLeft := uint64(0)\n\tfor {\n\t\t_, err := os.Stat(stagingDir)\n\t\tif err != nil {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn errors.Wrap(err, \"failed to read staging directory\")\n\t\t}\n\t\tstart := time.Now()\n\t\tsize, err := fileSizeInDir(stagingDir)\n\t\tif err != nil {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn errors.Wrap(err, \"failed to read staging directory\")\n\t\t}\n\t\tif lastLeft == 0 {\n\t\t\tlastLeft = size\n\t\t}\n\n\t\tif size == 0 && lastLeft == 0 {\n\t\t\treturn nil\n\t\t}\n\n\t\tspeed := uint64(0)","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/umount.go#L125-L161","documentation":"Wraps an os.Stat error on the writeback staging directory (<cache-dir>/rawstaging) during `juicefs umount --flush`; waitWritebackComplete polls this directory until all staging chunks are flushed. NotExist is treated as success (nothing staging); every other stat error (EACCES, EIO, ELOOP) is wrapped and aborts the unmount.","triggerScenarios":"Running `juicefs umount <mp> --flush` on a volume mounted with `--writeback` where the staging directory exists but cannot be stat'd: permission changed on the cache directory, the cache dir is on a failed/unmounted volume, or a symlink loop / I/O error on the cache path.","commonSituations":"Cache directory on an external disk that was detached; permissions tightened on cache-dir (e.g. run as different user than mount); cache dir pointing into the FUSE mount itself causing I/O errors once the mount degrades.","solutions":["Read the wrapped cause errno; fix permissions on the cache/rawstaging directory (`ls -ld <cache-dir>/rawstaging`)","Verify the volume hosting cache-dir is mounted and healthy","Point the mount's cache-dir to a healthy local path and remount before umount --flush","If the data is already flushed and the dir is broken, use umount without --flush or --force"],"exampleFix":"// before\njuicefs umount /mnt/jfs --flush   # EACCES on /var/jfsCache/rawstaging\n// after\nsudo ls -ld /var/jfsCache/rawstaging && sudo chmod 755 /var/jfsCache\nsudo juicefs umount /mnt/jfs --flush","handlingStrategy":"validation","validationCode":"staging := filepath.Join(cacheDir, \"rawstaging\")\nif _, err := os.Stat(staging); err != nil && !os.IsNotExist(err) { return fmt.Errorf(\"staging dir unreadable: %w\", err) }","typeGuard":null,"tryCatchPattern":"if err := waitWritebackComplete(staging); err != nil {\n\tlog.Printf(\"cannot check writeback staging: %v — verify cache dir health/permissions\", err)\n}","preventionTips":["Keep the cache directory on a healthy, always-mounted local volume","Do not change permissions on cache-dir while a mount is active","Check cache-dir reachability before umount --flush"],"tags":["umount","writeback","staging","cache","filesystem"],"backgroundTag":"file-read-failed","analyzedSha":"c9a67b23e8e08ec23ec331aa6f1675e2319e921c","analyzedAt":"2026-09-06T17:55:48.476Z","contentChangedAt":"2026-09-06T17:55:48.476Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}