dgraph-io/badger · error
no manifest found, required for read-only db
Error message
no manifest found, required for read-only db
What it means
When opening a badger directory in read-only mode, the MANIFEST file must already exist; badger will not create one in read-only mode. If OpenExistingFile reports the manifest missing and readOnly is set, this error is returned instead of creating a fresh manifest.
Source
Thrown at manifest.go:140
return helpOpenOrCreateManifestFile(opt.Dir, opt.ReadOnly, opt.ExternalMagicVersion,
manifestDeletionsRewriteThreshold, opt)
}
func helpOpenOrCreateManifestFile(dir string, readOnly bool, extMagic uint16,
deletionsThreshold int, opt Options) (*manifestFile, Manifest, error) {
path := filepath.Join(dir, ManifestFilename)
var flags y.Flags
if readOnly {
flags |= y.ReadOnly
}
fp, err := y.OpenExistingFile(path, flags) // We explicitly sync in addChanges, outside the lock.
if err != nil {
if !os.IsNotExist(err) {
return nil, Manifest{}, err
}
if readOnly {
return nil, Manifest{}, fmt.Errorf("no manifest found, required for read-only db")
}
m := createManifest()
fp, netCreations, err := helpRewrite(dir, &m, extMagic)
if err != nil {
return nil, Manifest{}, err
}
y.AssertTrue(netCreations == 0)
mf := &manifestFile{
fp: fp,
directory: dir,
externalMagic: extMagic,
manifest: m.clone(opt),
deletionsRewriteThreshold: deletionsThreshold,
}
return mf, m, nil
}
manifest, truncOffset, err := ReplayManifestFile(fp, extMagic, opt)View on GitHub (pinned to 2a001d466f)
Solutions
- Point ReadOnly opens at a directory that already contains a MANIFEST (an initialized DB)
- First open the directory read-write once (or copy the full directory including MANIFEST) before read-only access
- Verify the path is correct and the copy/backup completed fully
- Use badger info to confirm the directory contents
Example fix
// before
opts := badger.DefaultOptions("/path/to/empty-or-partial-dir")
opts.ReadOnly = true
// fails: no manifest found, required for read-only db
// after
// open read-write once to initialize, then open read-only
initOpts := badger.DefaultOptions("/path/to/dir")
db, err := badger.Open(initOpts) // creates MANIFEST
db.Close()
opts := badger.DefaultOptions("/path/to/dir")
opts.ReadOnly = true
db, err = badger.Open(opts) Defensive patterns
Strategy: validation
Validate before calling
// Go: check the manifest exists before a read-only open
if opts.ReadOnly {
if _, err := os.Stat(filepath.Join(opts.Dir, "MANIFEST")); os.IsNotExist(err) {
return fmt.Errorf("cannot open read-only: MANIFEST missing in %s", opts.Dir)
}
} Try / catch
// Go
db, err := badger.Open(opts)
if err != nil {
if strings.Contains(err.Error(), "no manifest found, required for read-only db") {
return fmt.Errorf("directory %s is not an initialized badger DB; open read-write once first", opts.Dir)
}
return err
} Prevention
- Only open read-only directories that were previously initialized read-write
- Include MANIFEST in every backup/copy of a badger directory
- Check the path points to the DB root, not a parent or subdir
- Initialize new DBs with a read-write open before read-only consumers start
When it happens
Trigger: badger.Open with opts.ReadOnly=true on a directory with no MANIFEST file (empty/new directory, or the manifest was deleted/not copied).
Common situations: Pointing a read-only reader at a non-existent or empty directory; copying a DB but excluding MANIFEST; opening a directory before a writer ever initialized it; read-only replicas started before initial sync.
Related errors
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/99b17424c193dbd3.
Report an issue: GitHub.