| Tested on | Ubuntu 25.04 (Plucky Puffin) |
|---|---|
| Package | useradd (passwd 1:4.16.0-7ubuntu1)shadow-utils |
| Applies to | Ubuntu, Debian, RHEL, AlmaLinux, Fedora, SUSE |
| Privilege | sudo or root |
| Man page | useradd(8) |
| Scope | useradd is the low-level shadow-utils command that creates local Linux accounts in /etc/passwd, /etc/shadow, /etc/group, and /etc/gshadow. Use flags such as -m, -u, -g, -G, -s, and -e to control home directories, IDs. |
| Related guides | How to create user in Linux Add user to group in Linux chage Linux commands |
useradd — quick reference
Basic user creation
Create local accounts. On most distros you still need passwd username before the user can log in with a password.
| When to use | Command |
|---|---|
| Create an account without creating a home directory | sudo useradd username |
Create an account and home directory with /etc/skel |
sudo useradd -m username |
| Skip home directory setup explicitly | sudo useradd -M username |
Custom home path (pair with -m to create the directory) |
sudo useradd -m -d /opt/app username |
Set login shell (path must exist and usually be listed in /etc/shells) |
sudo useradd -m -s /bin/bash username |
Set GECOS / comment field in /etc/passwd |
sudo useradd -m -c "Full Name" username |
UID and groups
Control numeric IDs and group membership at creation time. Primary groups must already exist unless you use -U or accept the default from /etc/default/useradd.
| When to use | Command |
|---|---|
| Assign a fixed UID (NFS or matching IDs across hosts) | sudo useradd -m -u 2001 username |
| Set primary group by name (group must exist) | sudo useradd -m -g GROUP username |
| Add supplementary groups at creation (comma-separated) | sudo useradd -m -G wheel,docker username |
| Create a private group with the same name as the user | sudo useradd -m -U username |
Do not create a private group (-N) |
sudo useradd -m -N username |
| Allow a duplicate UID (non-unique) | sudo useradd -o -m -u 2001 username2 |
System accounts
Low-UID service accounts for daemons. Pair with -M and /usr/sbin/nologin when the account should not log in interactively.
| When to use | Command |
|---|---|
| Create a system account (low UID from system range) | sudo useradd -r svcname |
| System account with no home and non-login shell | sudo useradd -r -M -s /usr/sbin/nologin svcname |
Account policy
Password expiry and inactivity rules feed into /etc/shadow via chage defaults.
| When to use | Command |
|---|---|
Set account expiry date (YYYY-MM-DD) |
sudo useradd -m -e 2027-12-31 username |
| Days of inactivity after password expires before account locks | sudo useradd -m -f 30 username |
Defaults and help
Inspect or change defaults stored in /etc/default/useradd and /etc/login.defs.
| When to use | Command |
|---|---|
Print current useradd defaults |
sudo useradd -D |
| Change default login shell for future users | sudo useradd -D -s /bin/bash |
| Show built-in usage text | useradd --help |
useradd — command syntax
useradd is the low-level binary from shadow-utils. Synopsis from useradd --help on Ubuntu 25.04 (passwd 1:4.16.0-7ubuntu1):
useradd [options] LOGIN
useradd -D
useradd -D [options]useradd writes to /etc/passwd, /etc/shadow, /etc/group, and /etc/gshadow. It does not set an interactive password unless you pass -p with a pre-hashed value — most admins run passwd username after creation instead.
On RHEL-family systems, /usr/sbin/adduser is often a symlink to useradd. On Debian and Ubuntu, adduser is a separate Perl wrapper — see the adduser.
useradd — command examples
Essential Create a login user with home directory and skel files
This is the most common portable pattern: create the account, create /home/username, and copy files from /etc/skel. You still need passwd before password login works.
Run the command:
sudo useradd -m -c "Lab User" -s /bin/bash labuser
sudo passwd labuseruseradd prints nothing on success. Set the password in the interactive passwd prompts, then verify:
getent passwd labuser
ls -la /home/labuserSample output:
labuser:x:1001:1001:Lab User:/home/labuser:/bin/bash
total 20
drwxr-x--- 2 labuser labuser 4096 Jul 1 13:47 .
drwxr-xr-x 4 root root 4096 Jul 1 13:47 ..
-rw-r--r-- 1 labuser labuser 220 Mar 5 2025 .bash_logout
-rw-r--r-- 1 labuser labuser 3771 Mar 5 2025 .bashrc
-rw-r--r-- 1 labuser labuser 807 Mar 5 2025 .profileWithout -m, many distros still record a home path in /etc/passwd but do not create the directory or copy skel files — that is why scripts almost always include -m.
Essential Account without -m — home path vs real directory
Show what happens when you omit -m: the passwd entry may list /home/username even when the directory was never created.
Run the command:
sudo useradd plainuser
getent passwd plainuser | cut -d: -f1,6
ls -d /home/plainuser 2>&1Sample output:
plainuser:/home/plainuser
ls: cannot access '/home/plainuser': No such file or directoryUse -m when you want a real home directory, or -M when you explicitly do not want one.
Essential Primary group and supplementary groups at creation
Create a user in an existing primary group and attach supplementary groups in one command — common for wheel, docker, or sudo access on portable scripts.
Run the command (create the groups first if needed):
sudo groupadd ops 2>/dev/null || true
sudo groupadd docker 2>/dev/null || true
sudo useradd -m -g ops -G docker deploy
id deploySample output:
uid=1002(deploy) gid=1003(ops) groups=1003(ops),1004(docker)-g sets the primary group. -G adds supplementary groups. To add groups to an existing user later, use usermod (-aG).
Common System service account (daemon pattern)
Service accounts use low UIDs and usually cannot log in interactively.
Run the command:
sudo useradd -r -M -s /usr/sbin/nologin mysvc
id mysvc
getent passwd mysvcSample output:
uid=994(mysvc) gid=984(mysvc) groups=984(mysvc)
mysvc:x:994:984::/home/mysvc:/usr/sbin/nologinThe home path may still appear in /etc/passwd even with -M; the important part is that no login shell session is available.
Common Fixed UID and custom home path
Useful when matching UIDs across NFS clients or aligning with documentation that specifies paths under /opt.
Run the command:
sudo useradd -m -u 7500 -d /opt/appdata appuser
getent passwd appuser
ls -ld /opt/appdataSample output:
appuser:x:7500:7500::/opt/appdata:/bin/sh
drwxr-x--- 2 appuser appuser 4096 Jul 1 13:50 /opt/appdataPick a UID that is free on the host (getent passwd | cut -d: -f3 | sort -n | tail). Sort numerically with sort -n so 10 follows 9; the sort command covers field separators and -k for columns.
Common Account expiry with -e
Create a temporary contractor or guest account that stops working after a calendar date.
Run the command:
sudo useradd -m -e 2027-06-30 guest1
sudo chage -l guest1 | grep -i expireSample output:
Account expires : Jun 29, 2027Confirm timezone interpretation if compliance teams care about the exact cutoff.
Advanced Inspect and change useradd defaults
Defaults affect every future useradd run until you change them again. Stored values come from /etc/default/useradd and /etc/login.defs.
Print current defaults:
sudo useradd -DSample output:
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/sh
SKEL=/etc/skelChange the default shell for new users:
sudo useradd -D -s /bin/bash
sudo useradd -D | grep SHELLSample output:
SHELL=/bin/bashDocument default changes in your change-management system — they affect every account created afterward.
Advanced Primary group does not exist (-g failure)
useradd -g requires the group to exist. This is a common script failure when provisioning order is wrong.
Run the command:
sudo useradd -m -g nosuchgroup failuser 2>&1Sample output:
useradd: group 'nosuchgroup' does not existCreate the group with groupadd first, or use -U to create a matching private group automatically.
useradd — when to use / when not
Choose useradd when you need the portable shadow-utils binary — especially in scripts, Ansible tasks, or on RHEL-family distros. Pick another tool when the job is interactive Debian admin or modifying existing accounts.
| Use useradd when | Use something else when |
|---|---|
|
|
useradd vs adduser
useradd is the core binary everywhere shadow-utils is installed. adduser behaviour depends on the distro — do not assume one global relationship.
| useradd | adduser | |
|---|---|---|
| Availability | Virtually all Linux distros | Debian/Ubuntu wrapper; on RHEL often adduser → useradd symlink |
| Style | Low-level, non-interactive by default | On Debian/Ubuntu: high-level Perl wrapper with prompts |
| Home directory | Needs -m to create home and skel |
Creates home and skel by default on Debian/Ubuntu |
| Portable scripts | Preferred | Debian-specific behaviour |
| Best on | RHEL, Fedora, AlmaLinux, portable automation | Ubuntu, Debian desktops and servers |
On Debian and Ubuntu, adduser calls useradd (and related tools) under the hood. On RHEL, ls -l /usr/sbin/adduser often shows a symlink to useradd — that is not the same as Debian’s adduser package.
See the adduser for Ubuntu/Debian interactive workflows.
useradd — interview corner
Practice these before exams or standups. Each card explains the idea in plain language, then ends with a short answer you can say aloud.
What is the useradd command in Linux?
useradd is the low-level account-creation binary from shadow-utils (Debian package passwd, RPM shadow-utils). It adds rows to /etc/passwd, /etc/shadow, /etc/group, and /etc/gshadow.
Unlike Debian’s interactive adduser wrapper, useradd does not prompt by default. You typically pass flags explicitly (-m for home, -G for groups) and run passwd afterward if the user needs password login.
A strong answer is:
"useradd is the portable shadow-utils tool for creating local Linux accounts. I use it in scripts and on RHEL-family systems with explicit flags like -m and -G, then set passwords with passwd."
What is the difference between useradd and adduser?
They are not always the same command:
- useradd — real binary on all major distros.
- adduser on Debian/Ubuntu — separate high-level wrapper with Debian policy defaults.
- adduser on RHEL — often a symlink to useradd, not the Debian wrapper.
Saying "useradd is a symlink to adduser" is wrong on Debian/Ubuntu and backwards on RHEL.
A strong answer is:
"useradd is the core utility everywhere. On Debian and Ubuntu, adduser is a friendlier wrapper that calls useradd internally. On RHEL, adduser is usually just a symlink to useradd — I pick useradd for portable scripts and adduser on Debian when I want interactive setup."
Why do you need useradd -m?
Without -m, useradd may still write a home path into /etc/passwd but often does not create the directory or copy /etc/skel files. That surprises people who expect a ready-to-use home folder.
-m (--create-home) creates the directory and copies skel files. Use -M when you explicitly do not want a home directory.
A strong answer is:
"I always use -m in scripts when the user needs a real home directory — without it you can get a passwd entry pointing at /home/user while the directory does not exist."
What is the difference between useradd -g and -G?
-g sets the primary group (one group — the account’s main GID in /etc/passwd).
-G sets supplementary groups (comma-separated list). The user still gets a primary group from -g, -U, or defaults.
Check with id username after creation.
A strong answer is:
"-g is primary group; -G is supplementary groups at creation time. I verify with id, and use usermod -aG later if I need to add more groups without recreating the user."
When do you use useradd -r?
-r creates a system account with a UID from the system range (for daemons and services). Pair it with -M and -s /usr/sbin/nologin when the account should not log in interactively.
A strong answer is:
"I use useradd -r for daemon accounts — low UID, no interactive login. I add -M and nologin when the service only needs file ownership, not an SSH session."
Troubleshooting
Common useradd failures — symptom, likely cause, and the fix to try first.
| Symptom | Likely cause | Fix |
|---|---|---|
Home directory missing after useradd |
Omitted -m |
sudo useradd -m username or create home manually and fix ownership |
group 'foo' does not exist |
-g points at missing group |
sudo groupadd foo first, or use -U |
Warning: missing or non-executable shell |
-s path not installed |
Install the shell or pick one from /etc/shells |
| User cannot log in | No password set | Run sudo passwd username |
UID already in use |
Duplicate -u |
Choose a free UID or add -o only if you truly need duplicate IDs |
Only root may add a user / permission errors |
Missing privilege | Prefix with sudo or run as root |
