| Tested on | RHEL 10.2 (Coughlan) |
|---|---|
| Package | systemd 257-23.el10_2.2 |
| Applies to | Ubuntu, Debian, Kali Linux, Linux Mint, Pop!_OS, Raspberry Pi OS, elementary OS, Zorin OS, Parrot OS, MX Linux, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux |
| Privilege | sudo or root for set-default, isolate, rescue, and emergency |
| Scope | Target concepts, get-default and set-default, isolate, list-dependencies, rescue and emergency targets, temporary boot overrides with systemd.unit=, and runlevel mapping. Does not cover full unit file authoring, su or sudo switching, service start/stop tutorials, or full GRUB configuration. |
| Related guides | systemctl command Boot and shutdown grubby command Linux command line RHCSA tutorial |
su or sudo, or editing GRUB entries beyond a one-line systemd.unit= override at boot.
A systemd target is not a mysterious runlevel number. It is a unit that groups other units and marks a synchronization point during boot: systemd starts dependencies, waits where targets say to wait, and leaves you in a defined system state such as multi-user text mode or a full graphical desktop.
What Is a systemd Target?
systemd manages work through units. A unit file describes something systemd can start, stop, or track—a service, a mount, a socket, or a target.
A target unit ends with .target. It usually does not run a long-lived process of its own. Instead it:
- Groups related services, mounts, and other units that belong together at a boot stage
- Acts as a synchronization point so systemd can order startup and signal “this milestone is reached”
- Pulls units into the transaction through dependencies such as
Requires=andWants=, whileAfter=andBefore=control startup and shutdown ordering
Think of multi-user.target as “the cluster of units that make a usable multi-user server” rather than a single daemon you restart.
On this lab host, both multi-user.target and graphical.target are active while the desktop is running—graphical target units sit on top of multi-user dependencies.
systemctl is-active multi-user.target graphical.target rescue.target emergency.targetSample output:
active
active
inactive
inactiverescue.target and emergency.target stay inactive during normal operation.
systemd Target Quick Reference
| Task | Command |
|---|---|
| Current default for next boot | systemctl get-default |
| Set default | systemctl set-default multi-user.target |
| Switch target now | systemctl isolate multi-user.target |
| Rescue mode | systemctl rescue |
| Emergency mode | systemctl emergency |
| List active target units | systemctl list-units --type=target |
| Show dependencies | systemctl list-dependencies multi-user.target |
isolate, rescue, and emergency change the running system. set-default affects future boots until you change it again.
Common systemd Targets
Administrators interact with a small subset of the 79 target unit files shipped on RHEL 10. The rest are internal milestones (local-fs.target, network-online.target, and similar).
| Target | Role |
|---|---|
basic.target |
Early “basic system” milestone after local filesystems and core initialization |
multi-user.target |
Multi-user system with command-line services—SSH, cron, logging, and typical server daemons |
graphical.target |
Multi-user plus graphical login (gdm and desktop stack) |
rescue.target |
Maintenance shell with local filesystems and sysinit dependencies |
emergency.target |
Minimal emergency shell with very few dependencies |
poweroff.target |
Shutdown and power-off transaction |
reboot.target and poweroff.target complete shutdown transactions—see boot and shutdown for systemctl reboot, poweroff, and scheduled shutdown workflows.
graphical.target depends on multi-user.target in the dependency tree, not beside it as a peer runlevel.
Check the Default Boot Target
The default target is the target systemd tries to reach on boot. It is stored as a symlink at /etc/systemd/system/default.target.
systemctl get-defaultSample output:
graphical.targetRead the symlink directly when you want the path systemd will follow:
readlink -f /etc/systemd/system/default.targetSample output:
/usr/lib/systemd/system/graphical.targetls -l /etc/systemd/system/default.targetSample output:
lrwxrwxrwx. 1 root root 40 Aug 3 11:45 /etc/systemd/system/default.target -> /usr/lib/systemd/system/graphical.targetget-default reports the name; readlink shows which file the symlink points at under /usr/lib/systemd/system/.
Change the Default Boot Target
Use set-default when a server should boot to text multi-user mode without a display manager, or when a workstation should return to graphical after maintenance.
Switch the next-boot default to multi-user:
sudo systemctl set-default multi-user.targetSample output:
Removed '/etc/systemd/system/default.target'.
Created symlink '/etc/systemd/system/default.target' → '/usr/lib/systemd/system/multi-user.target'.Confirm the change:
systemctl get-defaultSample output:
multi-user.targetThe running desktop does not disappear immediately. graphical.target can remain active until you reboot or isolate:
systemctl is-active graphical.targetSample output on this host right after set-default:
activeRestore graphical as the default when the lab or server should boot to a GUI again:
sudo systemctl set-default graphical.targetSample output:
Removed '/etc/systemd/system/default.target'.
Created symlink '/etc/systemd/system/default.target' → '/usr/lib/systemd/system/graphical.target'.Reboot and run get-default plus systemctl is-active graphical.target when you need to prove the full boot path—not only the symlink.
Switch to Another Target Immediately
systemctl isolate starts the named target and its dependencies, then stops units that are not required by that target unless they have IgnoreOnIsolate=yes.
That is how you move a live system from graphical to multi-user without editing the default symlink:
sudo systemctl isolate multi-user.targetBefore isolating a target over SSH, verify that networking and sshd are dependencies of the destination target. multi-user.target normally keeps them on RHEL, but custom configurations can differ. Prefer scheduling maintenance, testing on a console, or using set-default plus reboot when a hard cutover is acceptable.
List what is active on a normal graphical boot—you should see both graphical.target and multi-user.target.
systemctl list-units --type=target --state=active --no-pagerSample output (trimmed):
UNIT LOAD ACTIVE SUB DESCRIPTION
basic.target loaded active active Basic System
cryptsetup.target loaded active active Local Encrypted Volumes
getty.target loaded active active Login Prompts
graphical.target loaded active active Graphical Interface
integritysetup.target loaded active active Local Integrity Protected Volumes
local-fs-pre.target loaded active active Preparation for Local File Systems
local-fs.target loaded active active Local File Systems
multi-user.target loaded active active Multi-User System
network-online.target loaded active active Network is Online
network-pre.target loaded active active Preparation for Network
network.target loaded active active NetworkReturn to graphical on a desktop with:
sudo systemctl isolate graphical.targetFor day-to-day unit control outside target changes, see the systemctl command reference.
Understand Target Dependencies
Targets start other units. list-dependencies walks Requires=, Requisite=, Wants=, and related edges—useful when you ask “what does multi-user actually pull in?”
systemctl list-dependencies multi-user.target --no-pager | head -25Sample output:
multi-user.target
● ├─atd.service
○ ├─audit-rules.service
● ├─auditd.service
● ├─avahi-daemon.service
● ├─chronyd.service
● ├─crond.service
● ├─cups.path
● ├─cups.service
● ├─firewalld.service
○ ├─insights-client-boot.service
● ├─irqbalance.service
○ ├─kdump.service
● ├─libstoragemgmt.service
● ├─mcelog.service
○ ├─mdmonitor.service
● ├─ModemManager.service
● ├─NetworkManager.service
● ├─plymouth-quit-wait.service
○ ├─plymouth-quit.service
● ├─rhsmcertd.service
● ├─rsyslog.service
○ ├─smartd.service
● ├─sshd.service
○ ├─sssd.service● marks active units; ○ marks inactive ones still listed in the dependency tree.
Graphical target adds desktop units on top of multi-user:
systemctl list-dependencies graphical.target --no-pager | head -20Sample output:
graphical.target
● ├─accounts-daemon.service
● ├─gdm.service
○ ├─nvmefc-boot-connections.service
● ├─rtkit-daemon.service
● ├─switcheroo-control.service
○ ├─systemd-update-utmp-runlevel.service
● ├─tuned-ppd.service
● ├─udisks2.service
● ├─upower.service
● └─multi-user.target
● ├─atd.service
○ ├─audit-rules.service
● ├─auditd.service
...Property lines show the difference between hard requirements and soft wants:
systemctl show multi-user.target -p Requires -p Wants -p Conflicts --no-pagerSample output:
Requires=basic.target
Wants=avahi-daemon.service plymouth-quit.service systemd-update-utmp-runlevel.service mcelog.service NetworkManager.service tuned.service mdmonitor.service rhsmcertd.service audit-rules.service remote-cryptsetup.target ModemManager.service systemd-ask-password-wall.path vmtoolsd.service libstoragemgmt.service cups.service crond.service irqbalance.service systemd-logind.service insights-client-boot.service sshd.service sssd.service cups.path chronyd.service smartd.service remote-fs.target plymouth-quit-wait.service auditd.service rsyslog.service firewalld.service systemd-user-sessions.service getty.target atd.service kdump.service
Conflicts=rescue.service shutdown.target rescue.targetRequires= failures are binding; Wants= failures are tolerated. This article stops at target-level dependency reading—not a full unit-design tutorial.
Rescue Mode
Rescue mode is for repair when the system boots but you need a root maintenance environment with local filesystems available. RHEL documents rescue as mounting local file systems and starting required services before a rescue shell.
Enter rescue on a running system:
sudo systemctl rescuesystemctl rescue switches to rescue.target, similar to systemctl isolate rescue.target, but also sends a wall message to logged-in users. Use systemctl --no-wall rescue when you intentionally want to suppress that notification. systemd may still prompt for the root password before switching.
Inspect what rescue pulls in:
systemctl list-dependencies rescue.target --no-pager | head -15Sample output:
rescue.target
○ ├─rescue.service
○ ├─systemd-update-utmp-runlevel.service
● └─sysinit.target
● ├─dev-hugepages.mount
● ├─dev-mqueue.mount
● ├─dracut-shutdown.service
...Return to normal operation after repair:
sudo systemctl isolate multi-user.targetUse graphical.target instead when the host normally runs a desktop.
Emergency Mode
Emergency mode is smaller than rescue. The emergency target requires emergency.service and little else:
systemctl list-dependencies emergency.target --no-pagerSample output:
emergency.target
○ └─emergency.serviceNetworking, most mounts beyond root, and application services are not part of this tree. On RHEL 10, emergency mode mounts only the root filesystem, read-only, with no other local filesystems or network. Emergency helps when boot never reaches multi-user and you need a root shell on the console to fix unit files or fstab entries.
sudo systemctl emergencyEquivalent to systemctl isolate emergency.target. Expect a root password prompt and minimal tooling.
If you need to edit /etc/fstab or another file under /, remount root read-write first:
mount -o remount,rw /After changing /etc/fstab, run systemctl daemon-reload before you attempt to continue boot or isolate back to multi-user.
Rescue vs Emergency Mode
| Aspect | Rescue (rescue.target) |
Emergency (emergency.target) |
|---|---|---|
| Purpose | Filesystem repair, config fixes with mounts | Bare-minimum shell when boot is badly broken |
| Typical filesystems | Local filesystems from sysinit path | Root only, normally read-only |
| Networking | Not the focus; more units than emergency | Generally unavailable |
| Entry command | systemctl rescue |
systemctl emergency |
| Dependency depth | sysinit.target plus rescue.service |
emergency.service only |
| Return path | systemctl isolate multi-user.target or graphical.target |
Same after root cause is fixed |
Start with rescue when the system still boots and you need mounted volumes. Drop to emergency when even rescue dependencies fail.
Select a Target Temporarily from the Bootloader
You can boot into a different target once without set-default. At the bootloader, edit the kernel command line for the selected entry and append:
systemd.unit=rescue.targetor:
systemd.unit=emergency.targetOther common one-boot overrides include systemd.unit=multi-user.target when graphical startup fails.
The parameter applies only to that boot. After you remove it or pick the default menu entry again, the system follows default.target from /etc/systemd/system/.
Full GRUB menu editing, password protection, and persistent kernel arguments belong in bootloader guides such as grubby command—this section only names the systemd.unit= knob.
systemd Targets vs SysV Runlevels
Legacy documentation still mentions runlevels. systemd targets overlap the idea but are not numeric runlevels internally.
| Legacy runlevel | Typical systemd target | Notes |
|---|---|---|
| 0 | poweroff.target |
Shutdown |
1, s |
rescue.target |
Single-user maintenance |
| 2 | multi-user.target |
Legacy compatibility mapping |
| 3 | multi-user.target |
Traditional text multi-user runlevel |
| 4 | multi-user.target |
Legacy compatibility mapping; no distinct systemd state |
| 5 | graphical.target |
Graphical login |
| 6 | reboot.target |
Reboot |
Traditional SysV installations sometimes reserved runlevel 4 for site-specific services. systemd does not define a separate target for that legacy convention—systemd.unit=multi-user.target is the compatibility mapping for runlevels 2, 3, and 4.
On this RHEL 10 host, runlevel still prints the SysV compatibility view:
runlevelSample output:
N 5N means no previous runlevel recorded for this boot; 5 matches graphical mode. Prefer systemctl get-default and target names in automation—the mapping is approximate, not a guarantee that every unit matches old runlevel scripts.
Custom Targets
Sites sometimes define custom targets to group application stacks. That requires writing unit files with AllowIsolate=yes, dependency lines, and ordering—a topic for a dedicated systemd unit authoring guide.
For RHCSA-style administration, knowing how to read list-dependencies and switch existing targets is enough. Skip custom target design until you routinely maintain your own unit files.
Troubleshoot Target Problems
| Symptom | Likely cause | Fix |
|---|---|---|
Target not found / isolate fails |
Misspelled or nonexistent target | Check systemctl list-unit-files --type=target; .target may be omitted with isolate |
isolate fails or hangs |
Target conflicts or broken required unit | journalctl -xb; fix failing Requires= unit; try rescue |
| Boots to multi-user but default is graphical | set-default not applied or symlink overridden |
readlink -f /etc/systemd/system/default.target; re-run set-default |
| Graphical target active but no GUI | Display manager failed | systemctl status gdm; fix graphics stack—not the target symlink alone |
get-default disagrees with symlink |
Stale admin edit | Replace symlink with set-default instead of manual ln -sf |
| Rescue or emergency asks for root password | Expected security behavior | Authenticate as root on console or fix root credentials |
| Network lost after isolate to rescue | Rescue does not target network-online | Start NetworkManager or sshd manually if needed for remote repair |
| SSH drops after target isolation | sshd or networking was not required by the destination target |
Check target dependencies before remote isolation; use console or out-of-band access for rescue/emergency transitions |
Practical Target Examples
These steps mirror server maintenance: read the default, change it for headless boot, confirm the symlink, and inspect dependencies. The commands below stay on a running host; the reboot outcome is described separately so the sequence stays logical.
Check what the next boot will use:
systemctl get-defaultSample output:
graphical.targetPoint future boots at multi-user for a headless server profile:
sudo systemctl set-default multi-user.targetVerify the symlink—not only get-default:
ls -l /etc/systemd/system/default.targetSample output:
lrwxrwxrwx. 1 root root 41 Aug 8 14:46 /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.targetRemember the live GUI may still run until reboot:
systemctl is-active graphical.targetSample output immediately after set-default multi-user:
activeInspect what multi-user will start on the next boot:
systemctl list-dependencies multi-user.target --no-pager | head -15If you reboot before restoring graphical.target as the default, the system should start in multi-user mode with graphical.target inactive and runlevel typically reporting N 3. To switch the current session to graphical, run systemctl isolate graphical.target; to make graphical mode persistent again, run systemctl set-default graphical.target.
On a desktop lab host, restore graphical as the default when you finish so the next boot returns to a GUI:
sudo systemctl set-default graphical.targetsystemctl get-defaultSample output:
graphical.targetReferences
- systemd.special(7) — special target units including multi-user, graphical, rescue, and emergency
- systemctl(1) — get-default, set-default, isolate, rescue, and emergency
- systemd.unit(5) — Requires, Wants, and IgnoreOnIsolate
- Red Hat — Booting into a target system state — RHEL 10 default target, isolate, rescue, emergency, and
systemd.unit=at boot
Summary
systemd targets describe where boot should end up and which units belong to that milestone. multi-user.target groups the services that make a text-mode server usable; graphical.target layers a display manager and desktop stack on that tree. Targets synchronize boot—they are not simply renamed runlevel numbers.
Daily administration splits along two axes. systemctl get-default and set-default control the default.target symlink for future boots without necessarily changing what is running now. systemctl isolate, rescue, and emergency change the live system and can stop graphical or network units you still depend on—plan console or out-of-band access before isolating away from a desktop over SSH.
Rescue and emergency are repair entry points, not everyday modes. Rescue brings in sysinit and local filesystems; emergency is the smallest shell systemd offers. One-boot systemd.unit=rescue.target on the kernel line fixes a single failed boot without touching set-default. When dependencies confuse you, list-dependencies and systemctl show on the target explain which services multi-user or graphical actually wants.
For power-off and reboot transactions (poweroff.target, reboot.target), use the boot and shutdown guide. For unit start, stop, and enable outside target changes, keep the systemctl command reference nearby.

