{"record":{"id":"565ce1830e64a019","repo":"juicedata/juicefs","slug":"failed-to-parse-config","errorCode":null,"errorMessage":"failed to parse config","messagePattern":"failed to parse config","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/umount.go","lineNumber":114,"sourceCode":"\t}\n\treturn err\n}\n\nfunc umount(ctx *cli.Context) error {\n\tsetup(ctx, 1)\n\tmp := ctx.Args().Get(0)\n\tif ctx.Bool(\"flush\") {\n\t\traw, err := readConfig(mp)\n\t\tif err != nil {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\treturn fmt.Errorf(\"not a JuiceFS mount point\")\n\t\t\t}\n\t\t\treturn errors.Wrap(err, \"failed to read config\")\n\t\t}\n\n\t\tvar conf vfs.Config\n\t\tif err = json.Unmarshal(raw, &conf); err != nil {\n\t\t\treturn errors.Wrap(err, \"failed to parse config\")\n\t\t}\n\t\tif conf.Chunk.Writeback {\n\t\t\tstagingDir := path.Join(conf.Chunk.CacheDir, \"rawstaging\")\n\t\t\tif err := waitWritebackComplete(stagingDir); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdefer func() {\n\t\t\t\tsize, _ := fileSizeInDir(stagingDir)\n\t\t\t\tclearLastLine()\n\t\t\t\tif size == 0 {\n\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\"))","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/umount.go#L96-L132","documentation":"Wraps a json.Unmarshal failure when `juicefs umount --flush` parses the raw config bytes read from the mountpoint into vfs.Config. It means the bytes at the mountpoint config location are not valid JSON of the expected shape — effectively a corrupted or foreign config file.","triggerScenarios":"Running `juicefs umount <mp> --flush` where readConfig returns bytes that fail to parse: the mountpoint is not actually a JuiceFS mount (different file content at the config path), the config file was truncated/corrupted, or an incompatible JuiceFS version wrote a differently-shaped config.","commonSituations":"Path is a mountpoint of another filesystem whose config-like file is not JSON; manually edited or partially written config; version mismatch between client that wrote the format and client running umount.","solutions":["Inspect the raw config content at the mountpoint (`cat <mp>/.config` or equivalent) to see what is actually there","Confirm the path is a JuiceFS mountpoint (`mount | grep <mp>`) and not another filesystem","Retry without --flush if writeback waiting is not needed (this parse only happens with --flush)","Upgrade/downgrade so the umount client version matches the mounting client version"],"exampleFix":"// before\njuicefs umount /mnt/jfs --flush   # config not JSON -> parse error\n// after\nmount | grep /mnt/jfs             # verify it is a juicefs mount\njuicefs umount /mnt/jfs           # unmount without flush, or fix/remount correctly","handlingStrategy":"validation","validationCode":"raw, err := readConfig(mp)\nif err != nil { return err }\nif !json.Valid(raw) { return fmt.Errorf(\"%s is not a JuiceFS config (invalid JSON)\", mp) }","typeGuard":null,"tryCatchPattern":"if err := umountCmd(mp, false); err != nil {\n\tif strings.Contains(err.Error(), \"failed to parse config\") {\n\t\tlog.Printf(\"mountpoint config corrupt or foreign filesystem; retry without --flush\")\n\t}\n}","preventionTips":["Confirm the path is a JuiceFS mount (mount output) before --flush","Do not hand-edit the config exposed at the mountpoint","Keep client versions consistent between mount and umount"],"tags":["umount","json","config","unmarshal"],"backgroundTag":"json-unmarshal-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"}