LFCS 70 🐧 Changing Default Target
The default target is the systemd state the machine reaches after boot completes. Changing it is a persistent configuration decision: the new target governs the next startup, not the current session. The command that performs this change is systemctl set-default, and it works by replacing a single symbolic link at /etc/systemd/system/default.target . Everything else follows from that symlink—systemd reads it at boot, resolves the target it points to, and pulls in the units that target requires.
This chapter covers the mechanics of the change, the verification steps, the relationship between the default target and the running system, and the common scenarios where an administrator needs to switch between multi-user.target and graphical.target. It also covers why the change does not take effect immediately and how to handle the case where an immediate switch is also required.
Key point: systemctl set-default rewrites the default.target symlink for the next boot. It does not alter the running system. The command to change the current session is systemctl isolate, and the two are independent operations.
Why changing the default target exists
The server-versus-desktop problem. A machine installed with a graphical environment defaults to graphical.target, which starts a display manager, a compositor, and a session manager. A server that does not need these services should boot to multi-user.target instead, saving memory and reducing the attack surface. Changing the default target is how a system is converted from one posture to the other without reinstalling .
The resource problem. Every service pulled in by graphical.target consumes CPU, memory, and startup time. On a virtual machine or container host, that overhead is wasted. Setting the default to multi-user.target frees those resources for the workloads the machine actually runs. The change is reversible, which makes it a low-risk optimization.
The recovery problem. A system that fails during graphical startup—a broken display driver, a corrupted session manager configuration—may still boot fine to a text console. Changing the default to multi-user.target allows the administrator to log in, diagnose the graphical failure, and repair it without reinstalling or using a rescue image. The default target is a boot-time decision, and changing it is a legitimate recovery step.
The consistency problem. Documentation and scripts assume a particular boot state. A deployment script that expects a display manager to be running will fail on a system that boots to multi-user.target. Making the default explicit—and changing it deliberately rather than inheriting whatever the installer chose—removes an assumption that otherwise surfaces as a production incident.
a. Inspecting the Current Default
Before changing anything, the current default must be known. The systemctl get-default command reads the default.target symlink and prints the target name. It is a read-only operation and requires no privileges.
# Show the target the system will boot into next time
systemctl get-default
# Typical output: graphical.target
The symlink itself can be inspected directly to confirm what get-default is reading. The path is /etc/systemd/system/default.target, and its target is the unit file under /usr/lib/systemd/system/.
# Show the symlink and where it points
ls -l /etc/systemd/system/default.target
# Example: default.target -> /usr/lib/systemd/system/graphical.target
The distinction between the default target and the active target matters here. get-default reports the boot-time target regardless of what the system is currently doing. If the system was switched with isolate after boot, the default and the active state will differ, and get-default will still report the persistent configuration .
b. Setting a New Default Target
The systemctl set-default command takes a target name and rewrites the symlink. It requires root privileges. The target must be an existing unit file; a typo produces an error rather than a broken boot.
# Change the default to a text console for the next boot
sudo systemctl set-default multi-user.target
# Output shows the symlink removal and creation
The output is explicit about what changed: it removes /etc/systemd/system/default.target, then creates it anew pointing at /usr/lib/systemd/system/multi-user.target. This is the entire mechanism. The command does not start or stop any services, does not touch the running system, and does not require a reboot to complete—though the change is only observable at the next boot.
Verification follows the same read-only command used before the change.
# Confirm the new default
systemctl get-default
# Output: multi-user.target
Reverting is the same command with the previous target name. There is no separate undo operation.
# Restore the graphical default
sudo systemctl set-default graphical.target
The symmetry is intentional. The command sets the symlink to whatever target is named, and any valid target can be the default. The choice of multi-user.target and graphical.target is conventional, not mandatory.
c. Default Versus Running State
The most common misunderstanding about set-default is that it should change the current session. It does not. After running set-default multi-user.target on a graphical desktop, the display manager continues running, the graphical session continues, and the system remains in graphical.target until reboot. This is by design: the default target is a boot-time configuration, and the running system is a separate concern .
To change the running system, the command is systemctl isolate <target>.target. It starts the units the target requires and stops those it does not. It is immediate and temporary—a reboot returns the system to the default target, whatever that is .
# Switch the running system to a text console immediately
# This stops the display manager and graphical session
sudo systemctl isolate multi-user.target
The two commands address different questions. set-default answers “what should this system do after the next reboot?” isolate answers “what should this system do right now?” When both the immediate and persistent states need to change, both commands are required, and the order does not matter for the final result—only for what the administrator sees in between.
# Complete workflow: change now and for future boots
sudo systemctl set-default multi-user.target
sudo systemctl isolate multi-user.target
Running isolate on a remote SSH session to a target that stops networking will terminate the connection. multi-user.target keeps networking active, so it is safe in that specific case, but rescue.target and emergency.target are not. The isolation command should be used with awareness of what the target includes.
Complete Example Session
# ============================================
# PART 1: CHECK THE CURRENT DEFAULT TARGET
# ============================================
# Read the default.target symlink
systemctl get-default
# Output: graphical.target
# ============================================
# PART 2: INSPECT THE SYMLINK DIRECTLY
# ============================================
# Confirm what get-default is reading
ls -l /etc/systemd/system/default.target
# Output: default.target -> /usr/lib/systemd/system/graphical.target
# ============================================
# PART 3: CHANGE DEFAULT TO TEXT MODE
# ============================================
# Persistent change for the next boot
sudo systemctl set-default multi-user.target
# Output shows symlink removed and recreated
# ============================================
# PART 4: VERIFY THE CHANGE
# ============================================
# Confirm the symlink now points to multi-user.target
systemctl get-default
# Output: multi-user.target
# ============================================
# PART 5: OBSERVE THE RUNNING SYSTEM IS UNCHANGED
# ============================================
# The display manager is still running
systemctl is-active graphical.target
# Output: active (the session has not changed)
# ============================================
# PART 6: SWITCH THE RUNNING SYSTEM NOW
# ============================================
# Immediate, temporary change to match the new default
sudo systemctl isolate multi-user.target
# Graphical session stops; text console remains
# ============================================
# PART 7: CONFIRM RUNNING STATE
# ============================================
# Graphical target is no longer active
systemctl is-active graphical.target
# Output: inactive
# ============================================
# PART 8: RESTORE GRAPHICAL DEFAULT
# ============================================
# Revert the persistent configuration
sudo systemctl set-default graphical.target
systemctl get-default
# Output: graphical.target
# ============================================
# PART 9: REBOOT TO OBSERVE PERSISTENCE
# ============================================
# The default target takes effect at boot
sudo systemctl reboot
# After reboot, the system is in graphical.target
# because that is what default.target points to
# ============================================
# PART 10: VERIFY AFTER REBOOT
# ============================================
# Confirm the system booted into the expected target
systemctl get-default
systemctl is-active graphical.target
# Both should reflect graphical.target
The ten parts trace the full lifecycle: inspect, change, verify, observe the running system unaffected, switch the running system separately, revert, and confirm persistence after reboot. The crucial observation is in Part 5—the running system does not change when the default changes.
Quick Reference
Target Change Commands
| Command | Effect | Persistent |
|---|---|---|
systemctl get-default | Show next-boot target | N/A |
systemctl set-default <target> | Rewrite default.target symlink | Yes |
systemctl isolate <target> | Switch running system immediately | No |
ls -l /etc/systemd/system/default.target | Inspect the symlink | N/A |
Common Default Targets
| Target | When to Use |
|---|---|
multi-user.target | Servers, headless VMs, containers |
graphical.target | Desktops, workstations with display |
rescue.target | Single-user recovery (rarely default) |
State Inspection
| Command | Reports |
|---|---|
systemctl get-default | Configured default target |
systemctl is-active <target> | Whether target is currently active |
systemctl list-units --type=target | All active targets |
Best Practices
✅ Do This:
# Check the current default before changing
systemctl get-default # ✅
# Use set-default for persistent boot mode
sudo systemctl set-default multi-user.target # ✅
# Verify the symlink after the change
ls -l /etc/systemd/system/default.target # ✅
# Use isolate when the running system must change too
sudo systemctl isolate multi-user.target # ✅
# Revert with the same command and the previous target
sudo systemctl set-default graphical.target # ✅
# Confirm active state separately from default
systemctl is-active graphical.target # ✅
❌ Don’t Do This:
# Expect set-default to change the running session
sudo systemctl set-default multi-user.target # ❌ (no immediate effect)
# Assume isolate persists after reboot
sudo systemctl isolate multi-user.target # ❌ (temporary only)
# Use a target name that does not exist
sudo systemctl set-default text.target # ❌ (error)
# Isolate rescue.target over SSH
sudo systemctl isolate rescue.target # ❌ (drops connection)
# Edit the symlink manually instead of using set-default
ln -sf /usr/lib/systemd/system/multi-user.target /etc/systemd/system/default.target # ❌
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
No visible change after set-default | It only affects the next boot | Reboot, or use isolate |
| Default reverts after reboot | set-default was never run | Run set-default, then reboot |
| Target not found error | Typo or missing unit | Verify with systemctl list-unit-files --type=target |
| Remote connection lost | isolate stopped networking | Avoid isolating rescue/emergency remotely |
| Graphical session still running | Default changed but running state did not | isolate after set-default if immediate switch needed |
Real-World Examples
1. Convert Server to Text Boot
sudo systemctl set-default multi-user.target
2. Restore Desktop Graphical Boot
sudo systemctl set-default graphical.target
3. Verify the Change
systemctl get-default
4. Inspect the Symlink
ls -l /etc/systemd/system/default.target
5. Switch Immediately
sudo systemctl isolate multi-user.target
6. Confirm Graphical Is Inactive
systemctl is-active graphical.target
7. Complete Persistent and Immediate Change
sudo systemctl set-default multi-user.target && sudo systemctl isolate multi-user.target
8. Revert Persistent Change
sudo systemctl set-default graphical.target
9. Check Active Targets
systemctl list-units --type=target
10. Verify After Reboot
systemctl get-default && systemctl is-active graphical.target
Visual
The Symlink Mechanism
┌──────────────────────────────────────────────────────────────┐
│ BEFORE: │
│ │
│ /etc/systemd/system/default.target │
│ │ │
│ └──────► /usr/lib/systemd/system/graphical.target │
│ │
│ AFTER: systemctl set-default multi-user.target │
│ │
│ /etc/systemd/system/default.target │
│ │ │
│ └──────► /usr/lib/systemd/system/multi-user.target │
│ │
│ The command replaces one symlink. │
│ No services are started or stopped. │
│ The running system is untouched. │
│ │
└──────────────────────────────────────────────────────────────┘
Default Versus Running State
┌──────────────────────────────────────────────────────────────┐
│ SET-DEFAULT ISOLATE │
│ │
│ Changes: Changes: │
│ The default.target symlink Running system state │
│ │
│ Visible: Visible: │
│ After next reboot Immediately │
│ │
│ Persists: Persists: │
│ Yes No │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ set-default │ │ isolate │ │
│ │ multi-user │ │ multi-user │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Next boot: │ │ Now: │ │
│ │ text mode │ │ text mode │ │
│ │ │ │ │ │
│ │ Current session:│ │ Default: │ │
│ │ still graphical │ │ unchanged │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ To do both: run set-default, then isolate. │
│ │
└──────────────────────────────────────────────────────────────┘
The Complete Change Workflow
┌──────────────────────────────────────────────────────────────┐
│ ADMINISTRATOR DECIDES TO CHANGE BOOT MODE │
│ │
│ ┌─────────────────┐ │
│ │ 1. Inspect │ systemctl get-default │
│ │ current │ → graphical.target │
│ └────────┬────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 2. Set default │ systemctl set-default multi-user │
│ │ persistently │ → symlink rewritten │
│ └────────┬────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 3. Verify │ systemctl get-default │
│ │ symlink │ → multi-user.target │
│ └────────┬────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 4. Optional: │ systemctl isolate multi-user.target │
│ │ switch now │ → running session changes │
│ └────────┬────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 5. Reboot to │ systemctl reboot │
│ │ confirm │ → system boots to multi-user.target │
│ └─────────────────┘ │
│ │
│ Step 2 is required for persistence. │
│ Step 4 is required for immediate effect. │
│ They are independent. │
│ │
└──────────────────────────────────────────────────────────────┘
Target Selection Guide
┌──────────────────────────────────────────────────────────────┐
│ WHAT KIND OF SYSTEM IS THIS? │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Server │ │ Desktop │ │
│ │ Headless VM │ │ Workstation │ │
│ │ Container host │ │ Laptop │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ multi-user │ │ graphical │ │
│ │ .target │ │ .target │ │
│ │ │ │ │ │
│ │ Text console │ │ Display manager │ │
│ │ Networking │ │ GUI session │ │
│ │ No display mgr │ │ All of the above│ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ Both are reversible with the same command. │
│ Choose based on what the machine needs to do. │
│ │
└──────────────────────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
| Command to change default | systemctl set-default <target>.target |
| Persistent? | Yes, for next boot |
| Command to change running state | systemctl isolate <target>.target |
| Temporary? | Yes, reverts on reboot |
| Command to verify | systemctl get-default |
| Symlink location | /etc/systemd/system/default.target |
| Server target | multi-user.target |
| Desktop target | graphical.target |
| Both changes together | set-default then isolate |
Key takeaways:
set-defaultrewrites the symlink, nothing else. It removes/etc/systemd/system/default.targetand recreates it pointing at the chosen target. No services start or stop, and the running system is unaffected .- The change takes effect at the next boot. An administrator who runs
set-defaultand sees no immediate change has not encountered a bug; they have encountered the design. The new default governs the next startup. isolateis the command for the running system. It starts the target’s required units and stops those the target does not require. It is immediate and temporary, and it is the only way to change the current session without rebooting.- Both commands are needed for a complete change. When the default and the running state must both switch,
set-defaulthandles persistence andisolatehandles immediacy. The order does not change the final result. - Verification is a separate step.
systemctl get-defaultreads the symlink;systemctl is-activereads the running state. Checking one does not confirm the other, and a complete verification checks both.
Remember: The default target is a promise about the next boot. The active target is a fact about the current one. systemctl set-default changes the promise. systemctl isolate changes the fact. They are different commands because they answer different questions, and an administrator who understands which question they are asking will not be surprised by the result. For the LFCS exam, the objective is knowing that set-default is persistent and lazy, isolate is immediate and transient, and the symlink at /etc/systemd/system/default.target is the mechanism that connects them.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!