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

  1. Ensure the group ID passed to WriteGroupIdFile / RunBulkLoader / RunOfflineRestore is a nonzero value before the call
  2. Fix upstream logic that computes the group ID so it cannot remain 0 (assign groups before running the loader/restore)
  3. 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

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


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