{"record":{"id":"6a41d4db2c750567","repo":"dgraph-io/badger","slug":"file-already-exists-s","errorCode":null,"errorMessage":"file already exists: %s","messagePattern":"file already exists: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"table/table.go","lineNumber":253,"sourceCode":"}\n\nfunc (b *Block) verifyCheckSum() error {\n\tcs := &pb.Checksum{}\n\tif err := proto.Unmarshal(b.checksum, cs); err != nil {\n\t\treturn y.Wrapf(err, \"unable to unmarshal checksum for block\")\n\t}\n\treturn y.VerifyChecksum(b.data, cs)\n}\n\nfunc CreateTable(fname string, builder *Builder) (*Table, error) {\n\tbd := builder.Done()\n\tmf, err := z.OpenMmapFile(fname, os.O_CREATE|os.O_RDWR|os.O_EXCL, bd.Size)\n\tif err == z.NewFile {\n\t\t// Expected.\n\t} else if err != nil {\n\t\treturn nil, y.Wrapf(err, \"while creating table: %s\", fname)\n\t} else {\n\t\treturn nil, fmt.Errorf(\"file already exists: %s\", fname)\n\t}\n\n\twritten := bd.Copy(mf.Data)\n\ty.AssertTrue(written == len(mf.Data))\n\tif err := z.Msync(mf.Data); err != nil {\n\t\treturn nil, y.Wrapf(err, \"while calling msync on %s\", fname)\n\t}\n\treturn OpenTable(mf, *builder.opts)\n}\n\n// OpenTable assumes file has only one table and opens it. Takes ownership of fd upon function\n// entry. Returns a table with one reference count on it (decrementing which may delete the file!\n// -- consider t.Close() instead). The fd has to writeable because we call Truncate on it before\n// deleting. Checksum for all blocks of table is verified based on value of chkMode.\nfunc OpenTable(mf *z.MmapFile, opts Options) (*Table, error) {\n\t// BlockSize is used to compute the approximate size of the decompressed\n\t// block. It should not be zero if the table is compressed.\n\tif opts.BlockSize == 0 && opts.Compression != options.None {","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/table/table.go#L235-L271","documentation":"CreateTable builds a new sstable by opening the file with O_EXCL, which fails when the file already exists (z.NewFile). In that case CreateTable returns 'file already exists: <fname>' instead of overwriting, protecting existing table data from being clobbered.","triggerScenarios":"Calling CreateTable (directly or via flush/compaction paths like handleMemTableFlush, buildTable, createAndOpen) with a filename whose numbered table file already exists on disk — e.g. replaying an old memtable flush, re-running a compaction that picks the same table ID, or a crashed previous run leaving the file behind.","commonSituations":"Recovery after a crash mid-flush where the sstable was created but the manifest wasn't updated; rebuilding tables from a backup into a directory that already contains tables; concurrent processes writing tables to the same directory; manually re-running tools like buildTable on existing data.","solutions":["Delete or move the existing table file if it is stale (verify via badger info/manifest that it's unreferenced), then retry CreateTable","Use a fresh/unused table filename (unique table ID) — ensure the directory's next file ID is greater than any existing file","Recover the DB properly (open with Badger so the manifest is reconciled) instead of re-running flush/compaction manually against the same directory","For createAndOpen-style callers, treat this as expected when the table is already present and fall back to OpenTable"],"exampleFix":"// before\nt, err := CreateTable(mf, bd) // panics flow with 'file already exists: 000123.sst'\n// after\nif _, statErr := os.Stat(fname); statErr == nil {\n    return OpenTable(mf, table.Options{}) // table already built, just open it\n}\nt, err := CreateTable(mf, bd)","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(fname); err == nil {\n\t// file already exists — decide: open it or remove it\n\treturn nil, fmt.Errorf(\"table %s already present, refusing to rebuild\", fname)\n}","typeGuard":"func fileExists(path string) bool {\n\t_, err := os.Stat(path)\n\treturn err == nil\n}","tryCatchPattern":"mf, err := z.OpenMmapFile(fname, os.O_CREATE|os.O_RDWR|os.O_EXCL, bd.Size)\nif err == z.NewFile {\n\t// already exists: open the existing table instead\n\treturn OpenTable(mf, opts)\n} else if err != nil {\n\treturn nil, y.Wrapf(err, \"while creating table: %s\", fname)\n}","preventionTips":["Never reuse table file IDs; ensure new table IDs exceed the max existing ID in the directory","After a crash, run proper badger recovery instead of re-running flushes into the same dir","Only one process should write tables to a badger directory at a time","Before manual rebuilds, check the manifest for references to the target file"],"tags":["filesystem","file-conflict","sst"],"backgroundTag":"file-already-exists","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"}