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
- Inspect the postings directory: if group_id is a directory, the data dir is corrupt — remove/replace it or restore from a good backup
- Re-run the bulk loader or restore to regenerate a valid group_id file
- Check for mount points or init scripts that created a directory named group_id and fix them
- 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
- Never mkdir or mount anything at the group_id path inside postings directories
- Verify data directory integrity after manual copies, restores, or container volume changes
- Run the bulk loader/restore as the only mechanism that creates server state files
- Monitor mounts so a volume never shadows an individual file with a directory
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
- error while creating debug file: %s
- error while creating temporary directory: %s
- error while archiving debuginfo directory: %s
- p directory does not exist for group [%d]: [%s]
- failed to open BadgerDB at [%v]: %v
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/b3110331961425c4.
Report an issue: GitHub.