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

  1. Point ReadOnly opens at a directory that already contains a MANIFEST (an initialized DB)
  2. First open the directory read-write once (or copy the full directory including MANIFEST) before read-only access
  3. Verify the path is correct and the copy/backup completed fully
  4. 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

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.