EXAMTOPICS / TECHNOLOGY INSIGHTS

Red Hat EX200: systemd and Journal Troubleshooting on RHEL 10

RHEL 10 uses systemd to manage services, system state, dependencies, mounts, timers, sockets, and much of the boot process. Troubleshooting therefore becomes much faster when administrators read systemd state and the journal as one connected story instead of restarting services repeatedly and hoping the error disappears.

These skills are central to the current RHCSA EX200 scope and the wider Red Hat certifications path. The essential tools are systemctl for unit state and control and journalctl for time-ordered diagnostic evidence.

Think in units, not only services

A systemd unit represents a system resource. Service units manage daemons and processes, target units group units into system states, mount units represent file-system mounts, timer units schedule activation, socket units can activate services, and several other unit types participate in dependency graphs.

This matters because a failed service may actually be waiting on a mount, socket, device, or prerequisite service. Looking only at the daemon process can miss the dependency that prevented it from starting.

Use systemctl list-units to see loaded runtime units and systemctl list-unit-files to inspect installed enablement state. The distinction between a unit being loaded, active, enabled, or failed is fundamental to diagnosis.

Start with systemctl status, then go deeper

systemctl status name.service gives a compact first view: load state, active state, main process information, recent log lines, and failure reason when available. It is a triage command, not the complete investigation.

If a unit failed, use systemctl --failed to see whether related units also failed. systemctl cat shows the vendor unit plus overrides and drop-ins, which is often the fastest way to discover that local customization changed startup behavior. systemctl show exposes detailed properties for deeper analysis.

Always read the exact unit name. A package can install several related services, sockets, and timers, and troubleshooting the wrong unit leads to misleading conclusions.

The journal lets you narrow evidence by boot, unit, time, and priority

journalctl -b displays messages from the current boot. Filtering with -u name.service narrows output to a unit, while -p err focuses on errors and higher priorities. Time filters such as --since and --until are useful when an operator knows when the incident began.

Previous-boot logs are particularly valuable for crashes and boot failures because the system may be healthy by the time you log in again. Persistent journal configuration and retention therefore affect how much historical evidence is available.

Read context around the first failure, not only the final repeated error. Later messages often describe consequences, while the earliest error reveals the actual cause such as a missing file, permission problem, failed dependency, or invalid configuration.

Enablement and runtime state answer different questions

systemctl start activates a unit now. systemctl enable configures it to participate in future boot or target activation according to the unit’s install metadata. A service can therefore be running but disabled, or enabled but currently stopped.

When a service “does not start after reboot,” first determine whether it was enabled and which target wants it. When a service “will not start now,” focus on runtime status, configuration, dependencies, permissions, and journal messages.

Using systemctl is-enabled and systemctl is-active makes that distinction explicit and works well in scripts and troubleshooting checklists.

Dependencies and ordering are not the same thing

Systemd unit files can express dependency relationships such as Wants and Requires, and ordering relationships such as After and Before. Saying that one unit starts after another does not necessarily cause the other unit to be started; ordering and requirement are separate concepts.

This distinction explains many custom unit mistakes. An administrator adds After=network.target expecting it to guarantee a fully usable network dependency, or adds a requirement without the intended ordering. Read both the dependency and ordering directives when troubleshooting startup sequence.

systemctl list-dependencies and unit-file inspection help reveal the relationship graph. For boot performance or ordering issues, systemd analysis tools can identify which units delayed the path to the target state.

Use drop-ins instead of editing vendor unit files

Package-provided unit files normally live under /usr/lib/systemd/system. Administrator overrides belong under /etc/systemd/system, commonly as drop-in configuration. Editing the vendor file directly risks losing local changes during package updates and makes configuration history harder to understand.

systemctl edit name.service provides a controlled way to create an override. After creating or modifying unit files, run systemctl daemon-reload so systemd reloads definitions and rebuilds its dependency view. If the service is running and the changed directives require it, restart the unit after reloading.

systemctl cat is valuable because it shows the effective unit sources together, helping administrators see both vendor defaults and local customization.

Targets define system states and recovery modes

Targets group related units and act as synchronization points. multi-user.target represents a common non-graphical multi-user state, while other targets represent graphical startup, rescue, emergency, or shutdown states.

RHEL 10 documentation describes using rescue and emergency targets for recovery. Emergency mode is intentionally minimal and is useful when normal boot cannot complete. Administrators can also select a different target for one boot by changing the kernel command line with a systemd.unit= target.

Linux boot commands provide broader startup context. On RHEL, target-based recovery should be paired with journal analysis so the root cause is corrected before returning to normal boot.

Timers connect service troubleshooting with scheduled work

Systemd timers can schedule activation of service units and provide an alternative to traditional cron for many tasks. When a scheduled job fails, inspect both the timer and the service it activates. A timer can be healthy while the triggered service exits with an error.

Cron jobs explain the traditional scheduler. Systemd timers differ because they participate directly in unit dependencies, journal logging, and service lifecycle management.

Use systemctl list-timers to see upcoming and previous activations, then inspect the associated service and journal for execution results.

Build a repeatable failure-isolation workflow

When a service fails, first reproduce or confirm the failure with systemctl status. Inspect the current-boot journal for that unit, then check configuration and dependencies. If the failure began after an override, review the drop-in. If it occurs only during boot, inspect target ordering, mount availability, network readiness, and previous-boot logs.

Avoid clearing evidence too early. Repeated restarts can flood the journal and change timing. Capture the first useful error and relevant configuration before making multiple changes. Apply one correction at a time and verify both runtime status and expected behavior.

For RHCSA preparation, practice failures deliberately: invalid service configuration, wrong file permissions, missing environment files, failed mounts, disabled units, broken dependencies, and incorrect targets. The goal is not command memorization but the ability to move from symptom to systemd state to journal evidence to root cause.

Good systemd troubleshooting is evidence-driven

Systemd already records a rich model of what the system tried to do, which unit requested what, and where failures occurred. Administrators who understand units, targets, dependencies, enablement, and the journal can often explain an outage without guesswork.

RHEL 10 does not require a completely new troubleshooting philosophy; it requires disciplined use of the current systemd and journal interfaces. Start at the failed unit, follow dependencies outward, correlate events in time, and keep local overrides separate from vendor configuration.

The durable RHCSA skill is being able to answer three questions quickly: what state is the unit in, why did systemd put it there, and what evidence in the journal supports the diagnosis? Once those are clear, the corrective action is usually much safer.

Service failures can also be caused by the security and filesystem environment rather than the unit syntax. If a daemon starts manually but not through systemd, compare environment variables, working directory, user identity, file permissions, SELinux denials, and resource limits. Systemd deliberately starts services in a controlled context, so interactive-shell assumptions such as inherited PATH values or shell initialization files may not apply.

Boot-time troubleshooting benefits from comparing the critical path with ordinary service failures. Tools such as systemd-analyze can show total startup time and identify units that contribute to delay, but a slow unit is not automatically the root cause. It may be waiting correctly for storage, network, or another dependency. Combine timing information with dependency relationships and journal timestamps before disabling services simply because they appear near the top of a timing report.

Configuration validation should happen before restart when the service provides a native check command. Web servers, SSH, and other daemons often have syntax-test modes that can catch errors without taking the running service down. Systemd can tell you that the process exited, but the application-specific validator may explain why. Good troubleshooting uses systemd for lifecycle and dependencies while still using the daemon’s own diagnostic tools for application configuration.

After fixing a failure, verify persistence. A manual systemctl start proves only that the unit can run now; it does not prove the service will start under the intended target after reboot. Confirm enablement, dependencies, configuration files, and any required mounts so the repair survives the next system transition. That final check closes the gap between a temporary recovery and a durable repair.