{"record":{"id":"54a517792e557c7a","repo":"juicedata/juicefs","slug":"database-s-is-used-by-volume-s","errorCode":null,"errorMessage":"database %s is used by volume %s","messagePattern":"database (.+?) is used by volume (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/load.go","lineNumber":223,"sourceCode":"\t}\n\n\tmetaUri := ctx.Args().Get(0)\n\tremovePassword(metaUri)\n\tvar r io.ReadCloser\n\tif ctx.Args().Len() == 1 {\n\t\tr = os.Stdin\n\t\tsrc = \"STDIN\"\n\t} else {\n\t\tr, err = open(src, key, algo)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer r.Close()\n\t}\n\n\tm := meta.NewClient(metaUri, nil)\n\tif format, err := m.Load(false); err == nil {\n\t\treturn fmt.Errorf(\"database %s is used by volume %s\", utils.RemovePassword(metaUri), format.Name)\n\t}\n\n\tif ctx.Bool(\"binary\") {\n\t\tprogress := utils.NewProgress(false)\n\t\tbars := make(map[string]*utils.Bar)\n\t\tfor _, name := range meta.SegType2Name {\n\t\t\tbars[name] = progress.AddCountSpinner(name)\n\t\t}\n\n\t\topt := &meta.LoadOption{\n\t\t\tThreads: ctx.Int(\"threads\"),\n\t\t\tProgress: func(name string, cnt int) {\n\t\t\t\tbars[name].IncrBy(cnt)\n\t\t\t},\n\t\t}\n\t\tif err := m.LoadMetaV2(meta.WrapContext(ctx.Context), r, opt); err != nil {\n\t\t\treturn err\n\t\t}","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/juicedata/juicefs/blob/c9a67b23e8e08ec23ec331aa6f1675e2319e921c/cmd/load.go#L205-L241","documentation":"Before importing a backup, `load` calls meta.NewClient(metaUri).Load(false) to probe the target metadata engine. If the probe succeeds (a volume format is found), the database already belongs to a volume, and load refuses with `database <uri> is used by volume <name>` to avoid overwriting existing metadata. The URI is shown with its password removed.","triggerScenarios":"Running `juicefs load <META-URL> <backup>` against a metadata URL that already contains a formatted JuiceFS volume, e.g. re-restoring into a non-empty Redis DB or an existing SQLite file instead of a fresh/empty one.","commonSituations":"Re-running load after a partial restore; pointing at the live volume's metadata URL by mistake; leftover SQLite test.db from earlier experiments; reusing a Redis DB index that another volume occupies.","solutions":["Use a fresh/empty metadata URL (new SQLite file, unused Redis DB index) for the restore","If the target data is disposable, wipe it first (delete the sqlite file, FLUSHDB the Redis DB) and re-run load","Confirm you are not targeting the production volume's metadata URL — the volume name in the message tells you which one it is","If the same volume legitimately needs re-import, drop the old metadata engine before loading"],"exampleFix":"// before\njuicefs load redis://10.0.0.1/1 backup.json   # DB 1 already has volume 'myjfs'\n// after\njuicefs load redis://10.0.0.1/2 backup.json   # empty DB index","handlingStrategy":"validation","validationCode":"out, err := exec.Command(\"juicefs\", \"status\", metaUri).CombinedOutput()\nif err == nil {\n    return fmt.Errorf(\"meta engine already in use: %s\", out)\n}","typeGuard":null,"tryCatchPattern":"if err := loadCmd.Run(); err != nil {\n    if strings.Contains(err.Error(), \"is used by volume\") {\n        log.Fatalf(\"choose a fresh metadata URL: %v\", err)\n    }\n}","preventionTips":["Always restore into a fresh/empty metadata engine (new DB index or new sqlite file)","Never point restore jobs at production metadata URLs","Name restore targets distinctly and verify emptiness with juicefs status first"],"tags":["metadata","redis","backup-restore","conflict"],"backgroundTag":"metadata-engine-in-use","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"}