Linux Delete User: A Technical Deep Dive into userdel and What It Leaves Behind

`userdel` is one of those commands that looks trivial and is anything but. On the surface it deletes a Linux user. In practice it edits four flat files, optionally removes one directory, and then walks away — leaving behind a long tail of state that the manual rarely emphasizes: orphaned files scattered across the filesystem, a freed UID waiting to be reused, cron and `at` jobs, systemd user units, and sometimes a now-pointless private group. This guide treats `userdel` as the low-level tool it actually is, and shows you exactly what changes on disk, what does not, and how to clean up the remainder.

If you want the general, beginner-oriented walkthrough comparing the two main tools, read the companion piece . If you are specifically on Ubuntu and prefer the `deluser` wrapper, see . This article is the deep technical version: the internals, the edge cases, and the audit you should run afterward.

Key Takeaways
`userdel username` edits the account databases (`/etc/passwd`, `/etc/shadow`, `/etc/group`, `/etc/gshadow`) and keeps the home directory and every file the user owns.
`userdel -r username` additionally removes the home directory and the mail spool — and nothing else.
`userdel` refuses to run if the user is logged in or has running processes under most configs; clear them first with `pkill -u` and `loginctl`.
Files owned outside the home directory are never touched. They become orphaned files tied to a freed UID — a real risk if that UID is later reused. Always run `find / -uid OLD_UID`.
Cron jobs, `at` jobs, and systemd user units can survive deletion and must be cleaned up separately.

What does userdel actually modify on disk?

When you run `sudo userdel alice`, the command performs a precise, bounded set of edits. It is worth knowing them by name because everything else in this article follows from what is *not* on the list.

`userdel` removes the user’s entries from the four account databases:

  • `/etc/passwd` — the account record (UID, GID, GECOS, home, shell).
  • `/etc/shadow` — the hashed password and aging fields.
  • `/etc/group` — membership in any supplementary groups, and the user’s private group if one exists and is no longer used.
  • `/etc/gshadow` — the shadowed group administrative data.

That is the entire footprint of a plain `userdel`. The home directory, the mail spool, and every file the user owns anywhere on the system are left exactly as they were. The login name simply stops resolving.

You can confirm the account is gone with either of these:

“`bash id alice # -> “no such user” once deleted getent passwd alice # -> empty output “`

Before you delete anything, capture the UID — you will need it for the orphan sweep later, and once the `/etc/passwd` entry is gone, the name-to-number mapping is gone with it:

“`bash id -u alice # e.g. 1003 — write this down “`

What is the difference between userdel and userdel -r?

This is the single most consequential flag on the command, and it is narrower than most people assume.

“`bash

sudo userdel alice

sudo userdel -r alice “`

`-r` (`–remove`) deletes precisely two things beyond the account records: the user’s home directory (recursively) and the mail spool, typically `/var/mail/alice` or `/var/spool/mail/alice`. It does not scan the rest of the filesystem. A file the user created in `/srv/www`, a log they own in `/var/log`, a dump left in `/tmp` — none of these are candidates for removal, because `-r` only knows about the home and mail paths recorded for the account.

Here is the full breakdown of what each form of the command touches.

What `userdel alice` `userdel -r alice`
`/etc/passwd` entry Removed Removed
`/etc/shadow` entry Removed Removed
Supplementary group membership Removed Removed
Private user group (if unused) Removed Removed
Home directory (`/home/alice`) Kept Removed
Mail spool (`/var/mail/alice`) Kept Removed
Files owned outside `$HOME` Kept (orphaned) Kept (orphaned)
Cron / `at` jobs Kept Kept
systemd user units / lingering Kept Kept
Running processes Not killed (blocks deletion) Not killed (blocks deletion)

The right two columns are the point of this article. Even with `-r`, the bottom four rows survive.

Why does userdel fail when the user is logged in?

By default, `userdel` checks whether the account is in use and refuses to proceed if the user is currently logged in, with the message `userdel: user alice is currently used by process N` or `userdel: alice mail spool (/var/mail/alice) not found`. This is a safety interlock: deleting an account out from under a live session leaves the system in an inconsistent state.

Check for sessions and processes before deleting:

“`bash who | grep alice # active TTY/SSH sessions loginctl list-sessions # systemd-logind view of who is logged in loginctl user-status alice # sessions + lingering state for the user ps -u alice # every process owned by the user pgrep -u alice -l # cleaner process list with names “`

Clear them gracefully, then escalate only if needed:

“`bash sudo pkill -u alice # SIGTERM to all of alice’s processes sudo pkill -9 -u alice # SIGKILL if they refuse to exit “`

If the user has lingering enabled (systemd keeps a user manager running even with no session), terminate it explicitly so it does not respawn processes:

“`bash sudo loginctl disable-linger alice sudo loginctl terminate-user alice “`

`userdel` does offer a force flag, but understand what it does before you reach for it:

“`bash sudo userdel -f alice “`

`-f` (`–force`) deletes the account even while the user is logged in, removes the home directory and mail spool even if they are owned by another user, and removes the user’s group even if another user shares it as a primary group. It is blunt and can leave processes running under a UID that no longer maps to a name. Kill processes cleanly first; reserve `-f` for genuinely stuck states where you understand the consequences.

What gets left behind on the filesystem?

This is where a careful deletion separates itself from a sloppy one. `userdel` removes *records*, not *ownership*. Every inode the user owned keeps its numeric UID and GID, and most of those inodes live outside the home directory.

Find them by UID, not by name — the name no longer resolves once `/etc/passwd` is edited:

“`bash

sudo find / -xdev -uid 1003 -not -path “/proc/*” 2>/dev/null “`

`-xdev` keeps the search on one filesystem so you do not wander into NFS mounts or pseudo-filesystems; drop it if you genuinely need to cross mounts. Run the same query for the GID if the user had a private group that was removed:

“`bash sudo find / -xdev -gid 1003 -not -path “/proc/*” 2>/dev/null “`

Then decide per location — reassign what you keep, remove what you do not:

“`bash

sudo find / -xdev -uid 1003 -not -path “/proc/*” -exec chown svc_archive {} +

sudo find / -xdev -uid 1003 -not -path “/proc/*” -delete “`

The orphaned-UID trap is the real hazard of user deletion. `userdel` only removes the account *records* — and, with `-r`, the home directory and mail spool. It never hunts down files the user owns elsewhere on the filesystem. Those files do not vanish and they do not become “unowned”; they keep the user’s numeric UID as their owner, now detached from any name. They are orphaned files. The danger is UID reuse: when you next create a user without specifying a UID, `useradd` allocates the lowest free value in the `UID_MIN`–`UID_MAX` range — which may be exactly the UID you just freed. The new user then silently inherits ownership of every orphaned file the old user left behind, including anything sensitive in `/var`, `/srv`, or a web root. The fix is procedural, not accidental: record the UID before deletion, run `find / -uid OLD_UID` *after* deletion, and reassign or remove every hit. If you must guarantee the UID is never reused, reserve it by leaving a placeholder system account or raising `UID_MIN` past it.

What about cron jobs, at jobs, and systemd units?

These are the quietest survivors. None of them are removed by `userdel`, and several can keep executing code as a UID that no longer has a name.

User crontabs live in `/var/spool/cron/` (or `/var/spool/cron/crontabs/` on Debian/Ubuntu). They are *not* removed by `userdel`:

“`bash

sudo cat /var/spool/cron/crontabs/alice # path varies by distro sudo crontab -r -u alice # do this BEFORE deleting the account sudo rm -f /var/spool/cron/crontabs/alice # or remove the spool file directly after “`

`at` jobs are queued in `/var/spool/cron/atjobs` (or `/var/spool/at`). List and drain them by owner:

“`bash sudo atq # shows queued jobs and their owners sudo atrm # remove each job the user owns “`

systemd user services and lingering can outlive the account. If the user had `enable-linger` set, a per-user manager and its units may persist:

“`bash sudo loginctl disable-linger alice sudo rm -rf /var/lib/systemd/linger/alice

“`

The practical rule: drain cron, `at`, and systemd user state before you run `userdel`, while the name still resolves and the tooling still works cleanly.

How are groups handled during deletion?

`userdel` handles the user’s primary/private group and supplementary memberships differently, and the behavior depends on configuration.

On systems that use the user-private-group (UPG) scheme — the default on most modern distributions — each user gets a same-named group as their primary group. When you delete the user, `userdel` will remove that private group if no other user has it as their primary group. If `USERGROUPS_ENAB yes` is set in `/etc/login.defs` (the common default), this cleanup is automatic; if it is `no`, the private group lingers as an orphaned group and you remove it manually with `groupdel alice`.

For supplementary groups, `userdel` strips the user’s name from every group’s member list in `/etc/group`. If you only want to revoke one group membership *without* deleting the account, do it surgically rather than deleting and recreating:

“`bash

sudo gpasswd -d alice docker

id alice groups alice “`

Always confirm the user is gone from privilege groups specifically — `sudo`, `wheel`, `adm`, `docker`, `lxd` — since residual membership there is a security problem, not just untidiness.

How does deluser relate to userdel?

On Debian, Ubuntu, and derivatives, `deluser` is a high-level Perl wrapper that ultimately calls `userdel` (and `groupdel`) underneath, while adding conveniences `userdel` lacks: `–remove-home`, `–remove-all-files`, and `–backup` / `–backup-to`. It reads defaults from `/etc/deluser.conf`. On RHEL, CentOS, Fedora, AlmaLinux, Rocky, and Arch, `deluser` typically does not exist, so `userdel` is the portable choice — which is why scripts and automation should standardize on `userdel` for cross-distribution reliability. The Ubuntu-specific workflow is covered in the companion. The key technical point: whatever `deluser` does to the home directory, it has the same blind spot as `userdel` for files owned elsewhere — the orphan sweep is mandatory regardless of which front-end you use.

Manage Linux user accounts end to end with full root access

Everything in this guide — running `userdel`, sweeping `find / -uid` for orphaned files, reassigning ownership, draining cron and systemd state, auditing UID reuse — requires root on the actual machine. Shared hosting does not give you that, so you cannot enforce real account hygiene. A DarazHost VPS or dedicated server gives you complete root control to administer Linux users properly: delete accounts cleanly, locate and reassign orphaned files, audit UID allocation, and keep privilege groups tight across your whole environment. With reliable infrastructure, full control over your server, and 24/7 support, DarazHost is built for engineers who need a genuine Linux server rather than a locked-down sandbox.

A complete technical deletion procedure

Put the internals together into a sequence that leaves no residue:

  1. Record the UID and GID: `id alice` — you cannot resolve them after deletion.
  2. Drain user-scoped jobs while the name still works: `crontab -r -u alice`, clear `atq` entries, `loginctl disable-linger alice`.
  3. Check and stop sessions/processes: `loginctl user-status alice`, `pkill -u alice`, then `pkill -9 -u alice` if needed.
  4. Back up the home directory if the data could matter: `sudo tar -czf /root/alice-home.tar.gz /home/alice`.
  5. Delete the account: `userdel -r alice` (remove home + mail) or `userdel alice` (keep home).
  6. Sweep for orphaned files: `sudo find / -xdev -uid 1003 -not -path “/proc/*”` and `-gid 1003`; reassign or delete.
  7. Verify group cleanup: confirm removal from `sudo`/`wheel`/`docker`; `groupdel alice` if a private group lingered.
  8. Confirm: `id alice` returns “no such user” and the orphan sweep returns nothing.

Run in this order and you never lose data you needed, never leave executing jobs behind, and never hand a future user someone else’s files.

Frequently asked questions

Does userdel delete the user’s home directory? No — not by default. `userdel alice` edits only the account databases and leaves `/home/alice` and the mail spool intact. You must add `-r` (`userdel -r alice`) to remove the home directory and mail spool. Even with `-r`, files the user owns *outside* the home directory are never removed; they become orphaned files owned by the freed UID.

Why does userdel say the user is currently used by a process? The account has a live session or running processes, and `userdel`’s safety interlock refuses to delete an in-use account. Identify the processes with `ps -u alice` or `loginctl user-status alice`, stop them with `sudo pkill -u alice`, disable any lingering with `loginctl disable-linger alice`, then delete. As a last resort, `userdel -f alice` forces deletion, but it can leave orphaned running processes under a nameless UID.

What are orphaned files and why do they matter? Orphaned files are inodes still owned by a numeric UID that no longer maps to any account, because `userdel` removed the name from `/etc/passwd` without changing file ownership anywhere except (optionally) the home directory. They matter because the next user created may be assigned the same UID and silently inherit ownership of all those files — a privilege-escalation and data-leak risk. Sweep with `find / -uid OLD_UID` after every deletion.

Does userdel remove cron jobs and systemd user units? No. User crontabs in `/var/spool/cron`, queued `at` jobs, systemd lingering state in `/var/lib/systemd/linger`, and per-user unit files are not removed by `userdel`. Drain them explicitly — `crontab -r -u username`, `atrm`, `loginctl disable-linger username` — ideally before deleting the account while the name still resolves.

Will userdel remove the user’s private group? Usually yes. With the user-private-group scheme and `USERGROUPS_ENAB yes` in `/etc/login.defs`, `userdel` removes the same-named primary group if no other account uses it as a primary group. If that lingers, remove it manually with `groupdel username`. Supplementary group membership is always stripped from `/etc/group` during deletion.

About the Author

Leave a Reply