{"record":{"id":"27f95dc0dbb95923","repo":"dgraph-io/badger","slug":"duplicate-file-found-please-delete-one","errorCode":null,"errorMessage":"Duplicate file found. Please delete one.","messagePattern":"Duplicate file found\\. Please delete one\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"value.go","lineNumber":509,"sourceCode":"\tvlog.filesMap = make(map[uint32]*logFile)\n\n\tfiles, err := os.ReadDir(vlog.dirPath)\n\tif err != nil {\n\t\treturn errFile(err, vlog.dirPath, \"Unable to open log dir.\")\n\t}\n\n\tfound := make(map[uint64]struct{})\n\tfor _, file := range files {\n\t\tif !strings.HasSuffix(file.Name(), \".vlog\") {\n\t\t\tcontinue\n\t\t}\n\t\tfsz := len(file.Name())\n\t\tfid, err := strconv.ParseUint(file.Name()[:fsz-5], 10, 32)\n\t\tif err != nil {\n\t\t\treturn errFile(err, file.Name(), \"Unable to parse log id.\")\n\t\t}\n\t\tif _, ok := found[fid]; ok {\n\t\t\treturn errFile(err, file.Name(), \"Duplicate file found. Please delete one.\")\n\t\t}\n\t\tfound[fid] = struct{}{}\n\n\t\tlf := &logFile{\n\t\t\tfid:      uint32(fid),\n\t\t\tpath:     vlog.fpath(uint32(fid)),\n\t\t\tregistry: vlog.db.registry,\n\t\t}\n\t\tvlog.filesMap[uint32(fid)] = lf\n\t\tif vlog.maxFid < uint32(fid) {\n\t\t\tvlog.maxFid = uint32(fid)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (vlog *valueLog) createVlogFile() (*logFile, error) {\n\tfid := vlog.maxFid + 1","sourceCodeStart":491,"sourceCodeEnd":527,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/value.go#L491-L527","documentation":"Thrown by valueLog.populateFilesMap (value.go:509) when two files in the value-log directory resolve to the same uint32 file ID, i.e. duplicate '<id>.vlog' names exist. Since filesMap is keyed by fid, badger cannot disambiguate them and Open() fails.","triggerScenarios":"Two files with identical numeric names but different casing/paths that collapse to the same fid (e.g. '5.vlog' and '05.vlog' both parse to 5), or a genuinely duplicated file restored twice under names that hash to the same id.","commonSituations":"Manual restores where a copy was made as '5 (copy).vlog' renamed back to '5.vlog' alongside the original on a case-insensitive filesystem, backup tooling writing duplicate names, merging two data directories.","solutions":["Identify the duplicate ids (ls the dir, strip .vlog, find repeats) and delete the older/smaller one — badger explicitly instructs 'Please delete one'.","Compare file sizes/mtimes and keep the newest complete file; verify with a backup if unsure.","Never merge two badger data directories; restore one coherent snapshot instead.","On case-insensitive filesystems, ensure restores don't create same-id names differing only in case."],"exampleFix":"// before\n$ ls vlogdir\n5.vlog  05.vlog   # both parse to fid 5\n// after\n$ rm vlogdir/05.vlog   # or move it away; keep the correct one\n$ ls vlogdir\n5.vlog","handlingStrategy":"validation","validationCode":"// detect duplicate fids before opening badger\nfunc findDuplicateVlogIDs(dir string) (map[uint64]int, error) {\n    dups := map[uint64]int{}\n    files, err := os.ReadDir(dir)\n    if err != nil { return nil, err }\n    seen := map[uint64]struct{}{}\n    for _, f := range files {\n        n := f.Name()\n        if !strings.HasSuffix(n, \".vlog\") { continue }\n        id, err := strconv.ParseUint(n[:len(n)-5], 10, 32)\n        if err != nil { continue }\n        if _, ok := seen[id]; ok { dups[id]++ }\n        seen[id] = struct{}{}\n    }\n    return dups, nil\n}","typeGuard":"func fidOf(name string) (uint64, bool) {\n    if !strings.HasSuffix(name, \".vlog\") { return 0, false }\n    id, err := strconv.ParseUint(strings.TrimSuffix(name, \".vlog\"), 10, 32)\n    return id, err == nil\n}","tryCatchPattern":"dups, _ := findDuplicateVlogIDs(vlogDir)\nif len(dups) > 0 {\n    for id := range dups {\n        keep, drop := pickNewest(filepath.Join(vlogDir, fmt.Sprintf(\"%d.vlog\", id)))\n        _ = keep\n        os.Remove(drop) // or move to quarantine\n    }\n}\ndb, err := badger.Open(opts)","preventionTips":["Never merge or overlay two badger data directories into one.","Run one restore at a time and verify fid uniqueness before opening.","Use snapshots (badger backup/load or full-dir copy while stopped) rather than ad-hoc file juggling.","Monitor restore scripts for retries that could duplicate files."],"tags":["go","badger","value-log","duplicate-files","data-integrity"],"backgroundTag":"duplicate-log-file","analyzedSha":"2a001d466f6b71a917319a1db41f99860e16e269","analyzedAt":"2026-09-05T13:00:02.264Z","contentChangedAt":"2026-09-05T13:00:02.264Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}