dgraph-io/dgraph · error

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

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.

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)

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.