Changing Systemd Boot Target in Linux
Systemd Boot Targets
Systemd has replaced the traditional init system on most modern Linux distributions. With it came a shift in terminology—what used to be “runlevels” are now called “targets.” Understanding how to work with targets is essential for managing your system’s boot behavior and switching between different operational states.
Systemd Targets vs Init Runlevels
If you’re familiar with the old /etc/inittab runlevel system, here’s how systemd targets map to those legacy runlevels:
| Runlevel | Systemd Target | Purpose |
|---|---|---|
| 0 | poweroff.target |
Shutdown |
| 1 | rescue.target |
Single-user mode |
| 2, 3, 4 | multi-user.target |
Multi-user, no GUI |
| 5 | graphical.target |
Multi-user with GUI |
| 6 | reboot.target |
Reboot |
The two most commonly used targets are:
multi-user.target: Text-mode operation without a graphical interfacegraphical.target: Full desktop environment with X11/Wayland
Checking Your Current Target
Before making changes, it’s useful to see what target your system is currently set to:
systemctl get-default
This shows the default boot target. To see the currently active target:
systemctl list-units --type target --all
Switching to a Different Target Without Rebooting
You can change the active target immediately using isolate. This starts the specified target and its dependencies while stopping all others:
sudo systemctl isolate multi-user.target
Or to switch to graphical mode:
sudo systemctl isolate graphical.target
The isolate command is equivalent to changing runlevels with init 3 in traditional init systems. Note that isolating graphical.target from multi-user.target will start your display manager and X11/Wayland session, while isolating multi-user.target from graphical.target will stop your graphical environment and return you to a text login.
Be aware that isolate may interrupt running services. Use it cautiously in production environments.
Setting the Default Boot Target
To make a target the default for future boots, use set-default:
sudo systemctl set-default multi-user.target
Or for graphical mode:
sudo systemctl set-default graphical.target
Verify the change took effect:
systemctl get-default
You only need to run set-default once. The enable command is not necessary for targets—set-default handles both setting the symlink and managing the default target properly.
Switching to Rescue Mode
If you need to troubleshoot or perform system maintenance, you can boot into rescue.target:
sudo systemctl isolate rescue.target
This is similar to single-user mode in traditional init systems. It provides a minimal environment with only essential services running and requires the root password to proceed. You can also reboot directly into rescue mode on the next boot:
sudo systemctl set-default rescue.target
sudo reboot
Then switch back to your normal target afterward:
sudo systemctl set-default graphical.target
sudo systemctl isolate graphical.target
Manual Configuration (Not Recommended)
While systemctl set-default is the proper method, systemd targets are implemented via symlinks for those interested in the details. The default target is controlled by a symlink at /etc/systemd/system/default.target pointing to the actual target file in /usr/lib/systemd/system/.
You can view this symlink:
ls -l /etc/systemd/system/default.target
Manually editing the symlink is strongly discouraged—use systemctl set-default instead, as it handles the symlink correctly and integrates properly with systemd’s management tools.
Listing Available Targets
To see all available targets on your system:
systemctl list-unit-files --type target
Or to see targets that are installed but may not be enabled:
systemctl list-units --type target --all
Emergency and Emergency Targets
For extreme troubleshooting situations, systemd provides emergency.target. This boots with only the root filesystem mounted read-only and minimal services:
sudo systemctl isolate emergency.target
This requires the root password and is more restrictive than rescue.target. Use it only when rescue.target doesn’t provide enough isolation to diagnose and fix your problem.
thanks! good tutorial
aggreat!
Good article, thanks!
Is there a way to set the target via grub? I’d like to have an entry in my grub menu for booting to graphical/multi-user.
To put Ubuntu 19.04 into Runlevel 2 (Terminal):
sudo systemctl set-default multi-user.target
To reverse:
sudo systemctl set-default graphical.target
Is there a way to give a user with minimal permissions just the NON GUI access and the root user will have full GUI access? I basically have an Ubuntu system shared by multiple users. I want to be the root user with full access. On boot, when a non-root user logs in, it should boot to non-GUI version of Ubuntu with my app running. But when I login with my root account, I should have the GUI version boot up. Thank you!
If you have limited the non-root users’ ability to run your applications only, one possible way is to run the system in multi-user target/text mode. For root, after login, you can use
startxcommand to start the X session from the terminal.Of course you can restrict users from running certain applications, but if you are about to give them a general shell, they may still find a way to circumvent that. What you want is a restricted shell, e.g. add your app to “/etc/shells”, then set it as the shell of any restricted user in “/etc/passwd”. As long as your application doesn’t allow the user to break out of it, you should be fine.
As for the root user’s graphical environment, set just set your default to multi-user.target, then use startx after login to start your desktop. Disable or uninstall any display managers.
You don’t need to enable targets. At least on my system this produces an error message, and trying to disable one does nothing. Furthermore, since graphical.target depends on multi-user.target, it is active anyway. While in sysv-init, runlevels used to be separate from each other, systemd builds a dependency tree, so one target may include another.