systemd Service Failed to Start — How to Fix It

Updated Jun 2026 · originally published Jun 2026 · Tested on Ubuntu 24.04, Debian 12, RHEL 9, Rocky Linux 10

When a systemd service won’t start, the debugging path is always the same: check systemctl --failed, read the status, dig into the journal, and look at the exit code. The exit code tells you exactly where to look. This guide walks the full workflow and the most common causes.

The four-step workflow

# 1. What's failing?
systemctl --failed

# 2. Read the status — the bottom lines often show the actual error
systemctl status myapp.service

# 3. Get the full log for the service
journalctl -u myapp.service -n 50 --no-pager

# 4. Verify by running the start command manually (see below)

Most failures come down to a handful of causes: a wrong path, a missing user, bad permissions, a port conflict, or a config error. The journal almost always points straight at the culprit.

Reading the exit code

The status output and journal show an exit code that narrows the cause immediately:

Exit codeMeaningWhere to look
203/EXECsystemd couldn’t run the binaryCheck the ExecStart path exists and is executable
217/USERThe User= doesn’t existVerify the user with id <user>
216/GROUPThe Group= doesn’t existVerify the group
200/CHDIRWorkingDirectory= doesn’t existCheck the path
1199The application itself crashedRead the app’s own logs

To find the exit code:

systemctl status myapp.service | grep -i "main process"
# or
journalctl -u myapp.service | grep "Main process exited"

Cause 1 — Wrong binary path (203/EXEC)

systemd tried to run ExecStart and couldn’t find or execute it:

# Check the path the unit expects
systemctl cat myapp.service | grep ExecStart

# Verify it exists and is executable
ls -l /usr/bin/myapp
file /usr/bin/myapp

Fix the path in the unit file, then reload and restart (see the bottom of this page for the reload step).

Cause 2 — Missing user or group (217/USER)

# Does the user in the unit file exist?
systemctl cat myapp.service | grep -E "User|Group"
id myapp        # "no such user" means you found the problem

Either create the user or correct the User= line.

Cause 3 — Port already in use

A service that binds a port fails if another process already holds it:

# What's using port 80?
sudo ss -tlnp | grep :80

Stop the conflicting process or change the service’s port. Note that ports below 1024 require root or the CAP_NET_BIND_SERVICE capability.

Cause 4 — Config error

Most services can validate their own config before you restart:

sudo nginx -t                 # nginx
sudo apachectl configtest     # Apache
sudo sshd -t                  # SSH

Run the validator first — it’ll point at the exact line.

Cause 5 — ExecStartPre failed

If the unit has an ExecStartPre directive, a failure there stops the whole service before the main process even runs — easy to overlook:

systemctl cat myapp.service | grep ExecStartPre

A pre-start command that’s allowed to fail is prefixed with - (e.g. ExecStartPre=-/bin/somecheck).

The manual run trick

The most reliable way to see the real error is to run the start command yourself, as the service user, bypassing systemd entirely:

# Get the exact command
systemctl cat myapp.service | grep ExecStart

# Run it as the service user
sudo -u www-data /usr/bin/myapp --config /etc/myapp/config.yaml

Whatever error the app prints here is the error systemd was hiding.

On RHEL: don’t forget SELinux

On RHEL-family systems, a service that “works on my dev box but not in production” is very often an SELinux denial:

# Look for denials related to the service
sudo journalctl -u myapp.service | grep -i denied
sudo ausearch -m avc -ts recent

If that’s the cause, generate a policy with audit2allow or fix the file context with restorecon.

Clearing the failed state

After you fix the problem, systemd remembers the failure until you reset it:

sudo systemctl reset-failed myapp.service
sudo systemctl start myapp.service

After editing the unit file

Any change to the unit file needs a daemon reload before it takes effect:

sudo systemctl daemon-reload
sudo systemctl restart myapp.service
systemctl status myapp.service

Auto-restart on failure

For services that fail intermittently, configure systemd to restart them automatically. Add to the unit file with systemctl edit myapp.service:

[Unit]
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Restart=on-failure
RestartSec=5

This restarts on failure (but not on a clean exit), waiting 5 seconds between attempts, and gives up after 3 tries in 60 seconds. Note that the StartLimit* directives belong in [Unit], not [Service] — a common mistake.

FAQ

What does “Active: activating (auto-restart)” mean? The service is crashing and systemd is repeatedly trying to restart it. Read the journal to find why each attempt fails.

The service was killed — how do I know if it was the OOM killer? Check for out-of-memory kills: journalctl -b | grep -i "oom\|killed process". If the kernel killed it for memory, the service needs a memory limit raised or a leak fixed.

systemctl status only shows a few log lines — how do I see more? Use journalctl -u <service> -n 100 for the last 100 lines, or -xe for the most recent entries with explanations.

For the full command set see the systemctl reference, and for reading logs in depth see viewing logs with journalctl.


If you’re troubleshooting a production outage, work the steps in order — the exit code plus the journal almost always identifies the cause within a few minutes.