Understanding systemd Targets

multi-user, graphical, rescue, emergency

Systemd targets like multi-user, graphical, rescue, and emergency define system states managed via systemctl set-default and isolate commands.

You rebooted and the desktop is gone

You rebooted your Fedora machine after a routine kernel update and the screen drops to a blinking cursor with a login prompt instead of your desktop. Or maybe a failed filesystem check dropped you into a root shell with a Give root password for maintenance banner. You are not broken. You just landed in a different systemd target.

What targets actually do

Targets are not the old SysV runlevels. They are named collections of services and sockets that systemd starts together to reach a specific system state. Think of a target like a theater stage setup. The stage manager does not build the set from scratch every time. They pull a pre-made list of props, lights, and actors that belong together. When you boot into graphical.target, systemd loads the display manager, your desktop environment, network managers, and audio services. When you switch to multi-user.target, it keeps the network and SSH running but drops the display manager and desktop. The underlying services stay the same. Only the active collection changes.

Systemd achieves this through dependency trees. A target unit file contains a list of Wants= and Requires= directives. Wants= starts a service but continues booting if it fails. Requires= aborts the target if the dependency cannot start. This design lets you reach a functional state even when one component is broken. Targets also inherit from each other. graphical.target requires multi-user.target. multi-user.target requires basic.target. basic.target requires sysinit.target. When you request the graphical target, systemd walks down the chain and starts every dependency in order.

Run systemctl status first. Read the active state before guessing which target is active.

How to check and change targets

You will interact with targets using three primary commands. The first checks your current configuration. The second changes what happens on the next boot. The third switches the running system immediately.

Here is how to check which target systemd will use on the next startup.

systemctl get-default
# Returns the symlink target, usually graphical.target or multi-user.target
# This command only reads the configuration. It does not change anything.
# The output matches the file pointed to by /etc/systemd/system/default.target

Here is how to change the default boot target permanently.

sudo systemctl set-default multi-user.target
# Creates or updates a symlink at /etc/systemd/system/default.target
# The symlink points to /usr/lib/systemd/system/multi-user.target
# Changes take effect on the next reboot.

Here is how to switch targets without rebooting.

sudo systemctl isolate graphical.target
# Stops units not required by the new target
# Starts units required by the new target
# Fails immediately if a required dependency is masked or broken

The set-default command modifies a symlink in /etc/systemd/system/. Files in /etc/ are meant for administrator overrides. Files in /usr/lib/systemd/system/ ship with the packages. Never edit the files in /usr/lib/. Your changes will vanish on the next package update. You can also pass a target directly to the kernel at boot by adding systemd.unit=multi-user.target to the GRUB command line. This overrides the symlink for that single boot cycle.

Snapshot the system before the upgrade. Future-you will thank you.

Verify the change

Confirm the change by checking the symlink and the active state. The symlink tells you what will happen next. The active state tells you what is running right now.

Here is how to verify the symlink points to the correct target.

ls -l /etc/systemd/system/default.target
# Shows the symlink path and its destination
# A broken symlink here means systemd falls back to rescue.target
# The output should end with ../usr/lib/systemd/system/graphical.target

Here is how to check which target is currently active.

systemctl list-units --type=target --state=active
# Filters the unit list to show only loaded targets
# The active target appears with an active (active) state
# Other targets like basic.target or sockets.target will also show

If the output matches your intention, the configuration is correct. If the active target does not match the default, you are likely looking at a temporary switch caused by isolate or a boot parameter. You can also watch the journal for target transitions. The journalctl -xe command reads better than journalctl alone. The x flag adds explanatory text and the e flag jumps to the end. Most sysadmins type journalctl -xeu <unit> muscle-memory style.

Reboot before you debug. Half the time the symptom is gone.

Common pitfalls and exact error output

Switching targets fails when systemd cannot satisfy a dependency. The most common failure happens when you try to isolate graphical.target but the display manager service is masked or crashed. Systemd will refuse the switch and print a dependency failure.

Failed to isolate 'graphical.target': Dependency failed for 'graphical.target'.
See system logs and 'systemctl status graphical.target' for details.

Do not force the switch. Read the logs. The systemctl status command shows the exact unit that blocked the transition. Run journalctl -xeu gdm.service to see why the display manager failed. The error will usually point to a missing driver, a broken Xorg configuration, or a conflicting Wayland session. Fix the underlying service before attempting the target switch again.

Another common trap is landing in emergency.target after a disk check or SELinux relabel. The system drops to a minimal root shell because it cannot mount a filesystem or verify policy. The screen will show a warning about a failed mount or a request for the root password. This is not a hardware failure. It is a safety brake. Systemd stops the boot to prevent data corruption. SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux. Disabling the security module masks the real problem and leaves your system exposed.

Check the filesystem with fsck before remounting. Forcing a read-write mount on a corrupted disk spreads the damage.

When to use each target

Use graphical.target when you need a full desktop environment with a display manager and GUI applications. Use multi-user.target when you are running a headless server, a build machine, or a container host that only needs SSH and background services. Use rescue.target when the system fails to boot normally but the root filesystem is intact and you need a standard root shell with network access disabled. Use emergency.target when the root filesystem is corrupted, the initramfs is broken, or you need a minimal environment to repair disk partitions before anything else loads. Stay on the default graphical.target if you only deviate from the desktop occasionally.

Trust the package manager. Manual file edits drift, snapshots stay.

Where to go next