dgraph-io/dgraph · error

failed to open BadgerDB at

Error message

failed to open BadgerDB at [%v]: %v

What it means

Returned when badger.OpenManaged fails to open the posting-directory BadgerDB in read-only mode before streaming. The import client logs the same error with glog and wraps it for the caller. The pdir is a posting directory exported from the cluster, so a bad path or lock file blocks the entire group stream.

Solutions

  1. Verify pdir exists and is the correct group's posting directory (ls the dir, check for KEYREGISTRY/MANIFEST files).
  2. Ensure no other process (running Alpha or previous import) holds the directory lock; stop it or copy the directory.
  3. Check the filesystem is writable enough for lock/temp files even in ReadOnly mode.
  4. Match the badger library version to the one that produced the export.
  5. If corrupted, re-export the pdir from the cluster.

Example fix

// before
opt := badger.DefaultOptions(pdir)
ps, err := badger.OpenManaged(opt)
// after
if _, err := os.Stat(filepath.Join(pdir, "MANIFEST")); err != nil {
	return fmt.Errorf("invalid badger dir %q: run export first", pdir)
}
opt := badger.DefaultOptions(pdir)
opt.ReadOnly = true
ps, err := badger.OpenManaged(opt)
if err != nil {
	return fmt.Errorf("failed to open BadgerDB at [%v]: %v", pdir, err)
}
Defensive patterns

Strategy: validation

Validate before calling

func validateBadgerDir(pdir string) error {
	info, err := os.Stat(pdir)
	if err != nil || !info.IsDir() {
		return fmt.Errorf("pdir %q missing or not a directory", pdir)
	}
	for _, f := range []string{"MANIFEST", "KEYREGISTRY"} {
		if _, err := os.Stat(filepath.Join(pdir, f)); err != nil {
			return fmt.Errorf("pdir %q missing %s; re-run export", pdir, f)
		}
	}
	// lock probe: opening read-only will fail if another process holds the dir
	return nil
}

Try / catch

ps, err := badger.OpenManaged(opt)
if err != nil {
	if strings.Contains(err.Error(), "lock") {
		return fmt.Errorf("another process holds %q; stop Alpha or copy dir", pdir)
	}
	return fmt.Errorf("failed to open BadgerDB at [%v]: %v", pdir, err)
}

Prevention

When it happens

Trigger: badger.OpenManaged(opt) with a non-existent or wrong pdir path; another process still holds the BADGER.lock (e.g. a live Alpha using that directory); corrupted key-value files; read-only filesystem; badger version mismatch between writer and reader.

Common situations: Pointing the importer at the wrong directory (typo, wrong group's pdir); trying to open a directory in use by a running Alpha; export copied with missing/empty files; opening with a newer badger library than the one that wrote the data.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/99cfdce7bf7b4858. Report an issue: GitHub.

Appendix: source

Thrown at dgraph/cmd/dgraphimport/import_client.go:184

func streamSnapshotForGroup(ctx context.Context, dc api.DgraphClient, pdir string, groupId uint32) error {
	glog.Infof("Opening stream for group %d from directory %s", groupId, pdir)

	// Initialize stream with the server
	out, err := dc.StreamExtSnapshot(ctx)
	if err != nil {
		return fmt.Errorf("failed to start external snapshot stream for group %d: %w", groupId, err)
	}
	defer func() {
		_ = out.CloseSend()
	}()

	// Open the BadgerDB instance at the specified directory
	opt := badger.DefaultOptions(pdir)
	opt.ReadOnly = true
	ps, err := badger.OpenManaged(opt)
	if err != nil {
		glog.Errorf("failed to open BadgerDB at [%s]: %v", pdir, err)
		return fmt.Errorf("failed to open BadgerDB at [%v]: %v", pdir, err)
	}
	defer func() {
		if err := ps.Close(); err != nil {
			glog.Warningf("[import] Error closing BadgerDB: %v", err)
		}
	}()

	// Send group ID as the first message in the stream
	glog.Infof("[import] Sending request for streaming external snapshot for group ID [%v]", groupId)
	groupReq := &api.StreamExtSnapshotRequest{GroupId: groupId}
	if err := out.Send(groupReq); err != nil {
		return fmt.Errorf("failed to send request for group ID [%v] to the server: %w", groupId, err)
	}
	if _, err := out.Recv(); err != nil {
		return fmt.Errorf("failed to receive response for group ID [%v] from the server: %w", groupId, err)
	}

	glog.Infof("[import] Group [%v]: Received ACK for sending group request", groupId)

View on GitHub (pinned to 759e242be6)