dgraph-io/dgraph · error

Group ID file at %s is a directory

Error message

Group ID file at %s is a directory

What it means

ReadGroupIdFile reads the group_id file from a postings directory; it returns this error when the path exists but is a directory. A directory there means the data directory layout is corrupt or wrong, so the group ID cannot be determined and startup should abort.

Source

Thrown at x/file.go:173

	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.
func ReadGroupIdFile(pdir string) (uint32, error) {
	path := filepath.Join(pdir, GroupIdFileName)
	info, err := os.Stat(path)
	if os.IsNotExist(err) {
		return 0, nil
	}
	if info.IsDir() {
		return 0, errors.Errorf("Group ID file at %s is a directory", path)
	}

	contents, err := os.ReadFile(path)
	if err != nil {
		return 0, err
	}

	groupId, err := strconv.ParseUint(strings.TrimSpace(string(contents)), 0, 32)
	if err != nil {
		return 0, err
	}
	return uint32(groupId), nil
}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Inspect the postings directory: if group_id is a directory, the data dir is corrupt — remove/replace it or restore from a good backup
  2. Re-run the bulk loader or restore to regenerate a valid group_id file
  3. Check for mount points or init scripts that created a directory named group_id and fix them
  4. Never manually create the group_id path; let WriteGroupIdFile create it

Example fix

// before
$ mkdir -p /data/postings/group_id  # wrong: creates a directory where the file belongs
// after
$ ls -la /data/postings
$ rm -rf /data/postings/group_id   # remove the bogus directory
$ dgraph zero && dgraph alpha --postings /data/postings  # loader/write creates the file
Defensive patterns

Strategy: validation

Validate before calling

path := filepath.Join(pdir, "group_id")
info, err := os.Stat(path)
if err == nil && info.IsDir() {
    return fmt.Errorf("%s is a directory; restore or re-run the bulk loader to fix the data directory", path)
}

Type guard

func groupIdFileOK(pdir string) bool {
    info, err := os.Stat(filepath.Join(pdir, x.GroupIdFileName))
    return err == nil && !info.IsDir()
}

Try / catch

gid, err := x.ReadGroupIdFile(pdir)
if err != nil && strings.Contains(err.Error(), "is a directory") {
    return fmt.Errorf("postings dir %s corrupt at group_id; re-run bulk loader/restore", pdir)
}

Prevention

When it happens

Trigger: Calling ReadGroupIdFile on a postings directory where the entry named by GroupIdFileName is a directory instead of a regular file; called by runRestore and InitServerState when opening/restoring server state.

Common situations: Accidental directory creation at the group_id path (misconfigured volumes, wrong mount points, a recovery script that mkdir'd the path); partially copied or restored data directories; Docker/container mounts shadowing the file with a directory.

Related errors


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