Home / Alt manpages / groupdel(8)

  • groupdel(8)
  • Admin command
  • linux

Safely Delete a Linux Group with groupdel

groupdel looks like a one-line fix for group sprawl, until it deletes a group that was still someone's primary group. This guide removes an unused local group, after checking that no user has it as a primary group and that no files still depend on its numeric group ID. The examples use groupdel from the Ubuntu passwd package, version 1:4.13+dfsg1-4ubuntu3.2, implementing shadow-utils 4.13 behaviour.

Allow about 15 minutes for a normal local group. You need a shell, the group name, and root access for the final deletion. The checks before deletion are ordinary read-only commands. Deleting the group changes the local account databases and is not reversible by a single undo command, so do not start until you have a recovery copy.

1. Identify the group before changing anything

Set one obvious placeholder and confirm the group resolves to the record you expect. Replace GROUP_NAME with the exact local group name, never a broad pattern or a name copied from an untrusted request:

$ GROUP_NAME='GROUP_NAME'
$ getent group "$GROUP_NAME"
GROUP_NAME:x:1234:alice,bob

The numeric value in the third field is the group ID; your output will differ. If getent prints nothing, stop: the named group was not found through the configured name service, and groupdel will return status 6 for a group that does not exist. A group supplied by LDAP, NIS or another remote source is not a normal local deletion target.

Checkpoint

Write down the exact group name and ID from the output. Every later check in this guide must use those values, not a guessed number.

2. Check for users with this primary group

A user's primary group is the fourth field in the password database. List users whose primary ID matches the group:

$ GROUP_ID=$(getent group "$GROUP_NAME" | awk -F: 'NR == 1 { print $3 }')
$ getent passwd | awk -F: -v gid="$GROUP_ID" '$4 == gid { print $1 ":" $3 ":" $4 }'

No output is the safe result for an ordinary deletion. The fields shown are the login name, user ID and primary group ID. If a user appears, do not treat --force as a shortcut: the manual says -f can remove a group even when it is a user's primary group, but that leaves the account needing a deliberate replacement primary group. Change the user account and test its services separately, or keep the group.

Do not confuse supplementary membership with primary membership. The names after the fourth field in getent group are supplementary members; removing the group drops that supplementary membership, but does not touch a user's primary ID at all.

3. Find files still owned by the group

Deleting a group does not change file ownership. Files owned by the numeric ID will normally display the bare number once the group name disappears. Search each relevant local filesystem before deletion:

$ sudo find / -xdev -gid "$GROUP_ID" -print 2>/tmp/groupdel-owned-files.txt
$ sed -n '1,40p' /tmp/groupdel-owned-files.txt

sudo is needed because some directories cannot be searched by an ordinary user. -xdev stays on the root filesystem, so repeat the search on each mounted filesystem that matters. The output can be long, and access-denied diagnostics may still appear on unusual mounts. A non-empty result is not automatically a reason to delete the files: identify each owner and service, then either migrate the files to an appropriate group or keep the old group.

Do not run a recursive chgrp or delete files just to make this check come up empty. Those are separate, state-changing actions. If you deliberately migrate ownership, record the old paths and test the service before proceeding.

4. Save the account records

Make a private recovery directory and copy the two files that groupdel manages. Preserve metadata, and confirm the copies exist before continuing:

$ RECOVERY_DIR="${HOME}/groupdel-${GROUP_NAME}-backup"
$ mkdir -m 700 "$RECOVERY_DIR"
$ sudo cp --preserve=all /etc/group /etc/gshadow "$RECOVERY_DIR/"
$ sudo ls -l "$RECOVERY_DIR/group" "$RECOVERY_DIR/gshadow"

This command changes no account data yet. Keep the backup private, because /etc/gshadow contains protected group information, and store it under your normal administrative backup policy if the group matters to a managed host.

5. Review the deletion command

Check the installed command and its option syntax without changing state:

$ groupdel --help
Usage: groupdel [options] GROUP

Options:
  -h, --help                    display this help message and exit
  -R, --root CHROOT_DIR         directory to chroot into
  -P, --prefix PREFIX_DIR       prefix directory where are located the /etc/* files
  -f, --force                   delete group even if it is the primary group of a user

The installed help may also show package-specific options; this guide uses only the normal local operation. -R targets an absolute chroot directory, and -P prepares files under a prefix without chrooting. Leave both out unless you are deliberately operating on a target filesystem and have verified its account files.

6. Delete the group

Warning

This is the irreversible step for the local group record. Stop if the primary-user check produced output, if important files still use the ID, or if the backup check failed. Once the checks are clear, use root for the one command that changes the account files:

$ sudo groupdel "$GROUP_NAME"
$ printf 'groupdel exit status: %s\n' "$?"
groupdel exit status: 0

Status 0 means the command succeeded. It removes entries referring to the group from /etc/group and /etc/gshadow only: it does not remove files, change user accounts, stop services or repair ownership. Keep the recovery copy until verification and any service testing are complete.

  • Status 8: a user's primary group could not be removed. Re-run the primary-user check and resolve the account deliberately.
  • Status 10: the group file could not be updated. Do not keep retrying blindly; inspect permissions, filesystem state and any account-management lock before deciding whether a restore is needed.
  • Status 2: invalid syntax.
  • Status 6: the named group does not exist.

7. Verify the result and decide what to do about files

Confirm the name no longer resolves and that no password-database entry still uses the old primary ID:

$ getent group "$GROUP_NAME" || echo 'group name no longer resolves'
group name no longer resolves
$ getent passwd | awk -F: -v gid="$GROUP_ID" '$4 == gid { print $1 ":" $3 ":" $4 }'

Now re-run the ownership search if you need a post-change inventory:

$ sudo find / -xdev -gid "$GROUP_ID" -print 2>/tmp/groupdel-owned-files-after.txt

Existing files can still be owned by the numeric ID; that is expected, and is exactly why the pre-deletion inventory mattered. Do not assign the ID to a new group merely to make old files display a familiar name again unless you have reviewed the security consequences: a reused numeric ID can hand a new group access to old data.

Recovery if the deletion was wrong

There is no groupundel command. If you stopped services or changed ownership as part of a wider migration, use that service's documented rollback. For an accidental account-file deletion, preserve the current state first, pause account-management activity, and restore the saved group and gshadow files only during a planned maintenance window. The exact restore procedure depends on the host's account sources and any concurrent changes, so compare the backup with the current files before replacing anything.

Restoring the files does not recreate remote-directory membership or fix any ownership changes made separately. After a restore, run getent group "$GROUP_NAME", check the affected services, and review the system logs. Treat the backup as a recovery aid, not permission to overwrite newer account changes blindly.

Done means

  • Identity confirmed: the exact group name and numeric ID were confirmed before deletion.
  • No primary-group conflict: no existing user uses the group as its primary group.
  • Filesystems checked: relevant filesystems were searched for ownership by the numeric ID.
  • Backup verified: private copies of /etc/group and /etc/gshadow were confirmed.
  • Deletion succeeded cleanly: sudo groupdel GROUP_NAME returned status 0 without using --force.
  • Aftermath tracked: the group no longer resolves, and any remaining numeric ownership has an explicit owner and plan.