dgraph-io/dgraph · error
bulk output directory cannot be empty
Error message
bulk output directory cannot be empty
What it means
Import validates that bulkOutDir is non-empty before connecting. The bulk output directory is the root of the exported bulk-loader output whose per-group p/ subdirectories get streamed into the cluster, so an empty path is rejected outright.
Source
Thrown at dgraph/cmd/dgraphimport/import_client.go:45
// newClient creates a new import client with the specified endpoint and gRPC options.
func newClient(connectionString string) (api.DgraphClient, error) {
if connectionString == "" {
return nil, fmt.Errorf("connection string cannot be empty")
}
dg, err := dgo.Open(connectionString)
if err != nil {
return nil, fmt.Errorf("failed to connect to endpoint [%s]: %w", connectionString, err)
}
glog.Infof("[import] Successfully connected to Dgraph endpoint: %s", connectionString)
return dg.GetAPIClients()[0], nil
}
func Import(ctx context.Context, connectionString string, bulkOutDir string) error {
if bulkOutDir == "" {
return fmt.Errorf("bulk output directory cannot be empty")
}
dg, err := newClient(connectionString)
if err != nil {
return err
}
resp, err := initiateSnapshotStream(ctx, dg)
if err != nil {
return err
}
return streamSnapshot(ctx, dg, bulkOutDir, resp.Groups)
}
// isRetryableError returns true for transient errors that may resolve after a brief wait,
// such as Raft proposal backlogs during membership changes.
func isRetryableError(err error) bool {
if err == nil {View on GitHub (pinned to 759e242be6)
Solutions
- Pass the path to the bulk output directory (the one containing numeric per-group subdirectories with p/ inside).
- Validate the flag/env before calling Import.
- Ensure the bulk export step actually ran and its output path was captured.
- Check the directory layout matches group-ID subdirectories (e.g. 0/p, 1/p) after fixing the path.
Example fix
// before
err := dgraphimport.Import(ctx, addr, cfg.BulkDir) // cfg.BulkDir == ""
// after
if cfg.BulkDir == "" { return errors.New("bulk output directory is required") }
err := dgraphimport.Import(ctx, addr, cfg.BulkDir) Defensive patterns
Strategy: validation
Validate before calling
if err := validateBulkDir(bulkDir); err != nil { return err }
func validateBulkDir(dir string) error {
if strings.TrimSpace(dir) == "" {
return errors.New("bulk output directory is required")
}
fi, err := os.Stat(dir)
if err != nil || !fi.IsDir() {
return fmt.Errorf("bulk output dir %q not found", dir)
}
return nil
} Type guard
func validBulkOutDir(s string) bool { return strings.TrimSpace(s) != "" } Try / catch
if err := dgraphimport.Import(ctx, addr, bulkDir); err != nil {
if err.Error() == "bulk output directory cannot be empty" {
return fmt.Errorf("config error: bulk output dir flag/env not set")
}
return err
} Prevention
- Validate the bulk-dir flag/env at pipeline start.
- Capture the bulk command's output path into config immediately after running it.
- Check the directory exists and contains group subdirs before importing.
When it happens
Trigger: Calling dgraphimport.Import with bulkOutDir == "" — unset flag/env/config for the bulk output location.
Common situations: Forgot to pass the directory produced by `dgraph bulk`, pipeline variable empty in CI, running Import programmatically with a placeholder not yet filled.
Related errors
- connection string cannot be empty
- p directory does not exist for group [%d]: [%s]
- required field missing in Dgraph.Authorization:%s
- missing or empty directory
- ID written to group_id file must be a positive number
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/775081f80a31108f.
Report an issue: GitHub.