{"record":{"id":"ea1ec087ec3c73fc","repo":"juicedata/juicefs","slug":"unable-to-mount-s-v","errorCode":null,"errorMessage":"unable to mount %s: %v","messagePattern":"unable to mount (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/object/nfs.go","lineNumber":482,"sourceCode":"\t\tusername = u.Username\n\t}\n\tb := strings.Split(addr, \":\")\n\tif len(b) != 2 {\n\t\treturn nil, fmt.Errorf(\"invalid NFS address %s\", addr)\n\t}\n\thost := b[0]\n\tpath := b[1]\n\tmount, err := nfs.DialMount(host, time.Second*3)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to dial MOUNT service %s: %v\", addr, err)\n\t}\n\tauth := rpc.NewAuthUnix(username, uint32(utils.GetCurrentUID()), uint32(utils.GetCurrentGID()))\n\ttarget, err := mount.Mount(path, auth.Auth())\n\ttarget.Config.DirCount = 1 << 17\n\t// Readdir returns up to 1M at a time, even if MaxCount is set larger\n\ttarget.Config.MaxCount = 1 << 20\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to mount %s: %v\", addr, err)\n\t}\n\tumask := utils.GetUmask()\n\treturn &nfsStore{\n\t\tusername: username,\n\t\thost:     host,\n\t\troot:     path,\n\t\tfmode:    os.FileMode(0666 &^ umask),\n\t\tdmode:    os.FileMode(0777 &^ umask),\n\t\ttarget:   target}, nil\n}\n\nfunc init() {\n\tRegister(\"nfs\", newNFSStore)\n}\n","sourceCodeStart":464,"sourceCodeEnd":497,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/pkg/object/nfs.go#L464-L497","documentation":"newNFSStore mounts a local directory over an in-process NFS server (github.com/willscott/go-nfs) so JuiceFS can treat it as object storage. After Mount() returns an error, the wrapper is wrapped with 'unable to mount <addr>' so the caller knows which NFS address/path failed. Any failure inside the go-nfs Mount handshake (filesystem backend errors, connection setup) surfaces here.","triggerScenarios":"Calling CreateStorage(\"nfs\", ...) or mounting an NFS-style URL where the underlying nfsutil/filesystem backend cannot serve the target path, or mount.Mount returns an error for the given path/auth.","commonSituations":"Source path does not exist or is not accessible by the client user; UID/GID mismatch between the JuiceFS process and the path permissions; unsupported or broken path (e.g. symlink issues); go-nfs library version incompatible with the path type.","solutions":["Check the wrapped %v error to see the underlying go-nfs failure and fix the path/permissions it names","Verify the path exists and the current user (GetCurrentUID/GID) can read it","Ensure the path is an absolute directory suitable for the NFS backend","Retry after fixing; re-check go-nfs dependency version if the error is internal to the library"],"exampleFix":"// before\nstore, err := object.CreateStorage(\"nfs\", \"/data/export\", \"\", \"\", \"\")\n// after\nif _, err := os.Stat(\"/data/export\"); err != nil {\n\tlog.Fatalf(\"NFS export path missing: %v\", err)\n}\nstore, err := object.CreateStorage(\"nfs\", \"/data/export\", \"\", \"\", \"\")\nif err != nil {\n\tlog.Fatalf(\"unable to mount nfs: %v\", err)\n}","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(nfsPath); err != nil { return fmt.Errorf(\"nfs path check: %w\", err) }","typeGuard":null,"tryCatchPattern":"store, err := object.CreateStorage(\"nfs\", path, \"\", \"\", \"\")\nif err != nil && strings.Contains(err.Error(), \"unable to mount\") {\n\t// inspect wrapped cause, fix path/permissions, retry\n}","preventionTips":["Pre-check that the export path exists and is readable by the process UID/GID","Use absolute directory paths for NFS storage","Pin go-nfs dependency versions"],"tags":["nfs","mount","object-storage"],"backgroundTag":"http-request-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"}