dgraph-io/dgraph · error
ID written to group_id file must be a positive number
Error message
ID written to group_id file must be a positive number
What it means
WriteGroupIdFile persists a group ID into the group_id file inside a postings directory, and refuses to write a zero value because group IDs are 1-based; 0 signals an uninitialized/invalid group in Dgraph's Raft setup. The guard prevents creating a group_id file that would make a zero group look valid on subsequent reads.
Source
Thrown at x/file.go:147
}
}()
_, err = file.Readdir(1)
if err == nil {
return
} else if err != io.EOF {
return
}
err = ErrMissingDir
return
}
// WriteGroupIdFile writes the given group ID to the group_id file inside the given
// postings directory.
func WriteGroupIdFile(pdir string, group_id uint32) error {
if group_id == 0 {
return errors.Errorf("ID written to group_id file must be a positive number")
}
groupFile := filepath.Join(pdir, GroupIdFileName)
f, err := os.OpenFile(groupFile, os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
return nil
}
if _, err := f.WriteString(strconv.Itoa(int(group_id))); err != nil {
return err
}
if _, err := f.WriteString("\n"); err != nil {
return err
}
return f.Close()
}
// ReadGroupIdFile reads the file at the given path and attempts to retrieve the
// group ID stored in it.View on GitHub (pinned to 759e242be6)
Solutions
- Ensure the group ID passed to WriteGroupIdFile / RunBulkLoader / RunOfflineRestore is a nonzero value before the call
- Fix upstream logic that computes the group ID so it cannot remain 0 (assign groups before running the loader/restore)
- Reject group_id==0 at the pipeline entry point with a clearer configuration error
Example fix
// before
err := x.WriteGroupIdFile(pdir, cfg.GroupId) // panics with 'must be a positive number' when GroupId is 0
// after
if cfg.GroupId == 0 {
return fmt.Errorf("--group_id must be set (>=1); got %d", cfg.GroupId)
}
err := x.WriteGroupIdFile(pdir, cfg.GroupId) Defensive patterns
Strategy: validation
Validate before calling
if groupId == 0 {
return fmt.Errorf("group ID must be a positive number before calling WriteGroupIdFile (got %d)", groupId)
}
if err := x.WriteGroupIdFile(pdir, groupId); err != nil {
return fmt.Errorf("writing group_id file: %w", err)
} Type guard
func validGroupId(id uint32) bool { return id != 0 } Prevention
- Validate group IDs at CLI/config parsing time (reject 0 with a clear flag error)
- Unit-test bulk loader/restore entry points with an unset group to fail fast upstream
- Never write server state files manually; let the loader/restore path assign groups
When it happens
Trigger: Calling WriteGroupIdFile(pdir, 0) directly, or indirectly via RunBulkLoader or RunOfflineRestore when the bulk loader / restore pipeline computed a zero group ID (e.g. unset or failed group assignment before writing server state).
Common situations: Automated pipelines that run the bulk loader programmatically before assigning a group; restore tooling invoked with an unset group parameter; custom tooling copying zero-valued config structs into the loader.
Related errors
- NQuad failed sanity check. Subject: %q, Predicate: %q, Objec
- empty variable name in function call
- empty facetKeys not allowed
- error creating indexer for %s: %w
- bulk output directory cannot be empty
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/2d7137608c5e097c.
Report an issue: GitHub.