Skip to content

Latest commit

Β 

History

History
155 lines (119 loc) Β· 5.92 KB

File metadata and controls

155 lines (119 loc) Β· 5.92 KB
title systemd Failed to start unit
slug linux-systemd-failed-to-start-unit
technologies
systemd
linux
severity high
tags
systemd
service
unit
startup
production
related
linux-segmentation-fault
linux-too-many-open-files
last_reviewed 2026-06-27

systemd Failed to start unit

Error Message

Failed to start myapp.service - My Application.
systemd[1]: myapp.service: Main process exited, code=exited, status=203/EXEC
systemd[1]: myapp.service: Failed with result 'exit-code'.
systemd[1]: myapp.service: Scheduled restart job, restart counter is at 5.
systemd[1]: myapp.service: Start request repeated too quickly.

Description

Failed to start <unit> is systemd's report that a unit did not reach an active state. It is a summary β€” the actionable detail is the result line that follows: the exit status=/code=, the result (exit-code, signal, timeout, oom-kill, protocol), and the unit's own stdout/stderr in the journal. systemd's numeric status=NNN/NAME codes (e.g. 203/EXEC, 200/CHDIR, 217/USER) come from the service manager itself and pinpoint why the exec failed before your program even ran. "Start request repeated too quickly" means it has crashed enough times to trip the restart rate limit.

Technologies

  • systemd (service manager, unit execution)
  • linux (process exec, namespaces)

Severity

high β€” the service is not running. For a critical daemon this is a direct outage, and the restart loop can mask the root cause while the dependency graph fails other units that Requires= it.

Common Causes

  1. ExecStart= points at a missing/non-executable binary or wrong path β†’ 203/EXEC.
  2. A configured User=, Group=, WorkingDirectory=, or ReadWritePaths= doesn't exist or is wrong β†’ 217/USER, 200/CHDIR.
  3. The application itself exits non-zero on bad config / missing env / unreachable dependency β†’ status=1.
  4. The unit's sandboxing (ProtectSystem=, ReadOnlyPaths=, PrivateTmp=) blocks a path the app needs to write.
  5. A Type=notify/Type=forking mismatch or a slow start hitting TimeoutStartSec β†’ result 'timeout'.

Root Cause Analysis

systemd forks a helper that sets up the unit's execution environment β€” user, cgroup, namespaces, working directory, capabilities β€” then execve()s ExecStart=. If that setup or the exec fails, systemd reports a 2xx status code generated by the manager (the program never ran). If the program does run and exits non-zero, you get its real exit status and its log lines. The Restart= policy plus StartLimitIntervalSec/StartLimitBurst then governs retries; once the burst limit is exceeded systemd gives up with "Start request repeated too quickly" and leaves the unit failed. Reading systemctl status and journalctl -u together tells you which half β€” manager setup vs application β€” failed.

Diagnostic Commands

# Headline state, last exit code/result, and recent log tail
systemctl status myapp.service --no-pager -l

# Full logs for the unit from this boot (the real error lives here)
journalctl -u myapp.service -b --no-pager | tail -50

# The effective, merged unit definition (catch a bad ExecStart/User/path)
systemctl cat myapp.service
systemctl show myapp.service -p ExecStart -p User -p WorkingDirectory -p Restart

# Why it won't start: failed dependencies / ordering
systemctl list-dependencies --failed

Expected Results

$ systemctl status myapp.service
● myapp.service - My Application
     Active: failed (Result: exit-code)
    Process: 4821 ExecStart=/usr/local/bin/myapp (code=exited, status=203/EXEC)

$ journalctl -u myapp.service -b | tail
systemd[1]: myapp.service: Failed at step EXEC spawning /usr/local/bin/myapp: No such file or directory

Failed at step EXEC ... No such file or directory with status=203/EXEC means the binary path is wrong or not executable β€” a manager-side failure, not an app bug. A plain status=1 with app log lines means the application chose to exit.

Resolution

  1. Read the journal first and act on the specific result:

    • 203/EXEC β†’ fix the ExecStart= path; chmod +x the binary; check it exists for the configured User=.
    • 217/USER β†’ create the missing user/group or correct the name.
    • 200/CHDIR β†’ create/fix WorkingDirectory=.
    • app status=1 β†’ fix the config/env/dependency the app complains about.
  2. If sandboxing blocks a needed path, add it to ReadWritePaths= or relax the specific protection β€” minimally, not by disabling all hardening.

  3. After editing the unit, reload then restart:

    sudo systemctl daemon-reload
    sudo systemctl reset-failed myapp.service   # clear the rate-limit counter
    sudo systemctl restart myapp.service
  4. For timeouts, fix the readiness signal (Type=notify + sd_notify) or raise TimeoutStartSec= only if the start is legitimately slow.

Validation

systemctl is-active myapp.service     # expect: active
systemctl status myapp.service        # Active: active (running), no restart loop
journalctl -u myapp.service -f        # expect steady output, no new failures

Prevention

  • Validate ExecStart paths and User= existence in CI / on deploy.
  • Keep Restart=on-failure with sane StartLimitBurst so loops surface fast.
  • Add hardening paths (ReadWritePaths=) alongside the protection that needs them.
  • Use Type=notify for accurate readiness instead of guessing timeouts.
  • systemd-analyze verify myapp.service in CI to catch unit syntax errors.

Related Errors

References

Tags

systemd Β· service Β· unit Β· startup Β· production