{"record":{"id":"de8fe2601df14a64","repo":"juicedata/juicefs","slug":"failed-to-create-plain-backup-s-w","errorCode":null,"errorMessage":"failed to create plain backup %s: %w","messagePattern":"failed to create plain backup (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/load.go","lineNumber":178,"sourceCode":"\tif key == \"\" && !isCompress {\n\t\treturn path, nil\n\t}\n\n\tnPath := path[:strings.LastIndex(path, \".\")]\n\tif utils.Exists(nPath) {\n\t\tlogger.Infof(\"plain backup %q already exists, skip conversion\", nPath)\n\t\treturn nPath, nil\n\t}\n\n\tr, err := open(path, key, algo)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer r.Close()\n\n\tw, err := os.Create(nPath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create plain backup %s: %w\", nPath, err)\n\t}\n\tdefer w.Close()\n\n\tif _, err = io.Copy(w, r); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to convert %s to %s: %w\", path, nPath, err)\n\t}\n\tlogger.Infof(\"converted backup %q to %q\", path, nPath)\n\treturn nPath, nil\n}\n\nfunc load(ctx *cli.Context) error {\n\tsetup0(ctx, 1, 2)\n\n\tkey, algo := ctx.String(\"encrypt-rsa-key\"), ctx.String(\"encrypt-algo\")\n\tsrc := ctx.Args().Get(1)\n\tvar err error\n\tif ctx.Bool(\"binary\") {\n\t\tif ctx.Bool(\"stat\") {","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/load.go#L160-L196","documentation":"When converting a (possibly encrypted/binary) backup to plain JSON, `convert` creates the destination plain-backup file with os.Create(nPath). If creation fails, the error is wrapped as `failed to create plain backup <nPath>: <error>`. This is a local filesystem write failure before any data is copied.","triggerScenarios":"os.Create fails because the target directory does not exist, the path is a directory, the disk is full, or the process lacks write permission on the destination (e.g. / or a read-only mount as nPath's directory).","commonSituations":"Redirecting converted output into a read-only volume; SELinux/AppArmor denials; running as non-root while writing to /var/lib/juicefs; typo'd directory in the target path.","solutions":["Check that the destination directory exists and is writable (`ls -ld $(dirname <nPath>)`)","Free disk space if the filesystem is full (df -h)","Run as a user with write permission on the destination, or pick another output path","Check dmesg/audit logs for read-only remounts or LSM denials"],"exampleFix":"// before\njuicefs load meta.sqlite3 backup.json --output /root/jfs/converted.json   # non-root user\n// after\njuicefs load meta.sqlite3 backup.json --output ~/converted.json","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(nPath)\nif fi, err := os.Stat(dir); err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"output dir missing: %s\", dir)\n}\nif err := unix.Access(dir, unix.W_OK); err != nil {\n    return fmt.Errorf(\"output dir not writable: %s\", dir)\n}","typeGuard":null,"tryCatchPattern":"if err := convert(path, nPath); err != nil {\n    var pe *fs.PathError\n    if strings.Contains(err.Error(), \"failed to create plain backup\") {\n        log.Fatalf(\"fix destination dir/permissions: %v\", err)\n    }\n}","preventionTips":["Pre-check destination disk space and writability before conversion","Write outputs to a dedicated writable directory owned by the running user","Watch for read-only remounts after disk errors"],"tags":["filesystem","file-write","backup-restore"],"backgroundTag":"file-write-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"}