systemd: Failed to Start Service (exit code 203/EXEC)

Linux high systemdservicepermissions
Job for myapp.service failed because the control process exited with error code.
See "systemctl status myapp.service" and "journalctl -xeu myapp.service" for details.
Process: 812 ExecStart=/opt/myapp/bin/myapp (code=exited, status=203/EXEC)

What you see

systemctl status myapp reports a failed unit, and the journal shows status=203/EXEC. The service never reaches your application code, so there is no stack trace and no log line from the app itself.

Why it happens

203/EXEC means systemd called execve() on the path in ExecStart and the kernel refused. In practice it is one of six things:

  • the path does not exist, or is a relative path
  • the file exists but has no execute bit
  • the interpreter in the shebang line is missing
  • the filesystem is mounted with noexec
  • SELinux or AppArmor blocks execution
  • the unit was edited but never reloaded

Fix

1. Read the exact path systemd tried.

systemctl cat myapp.service | grep -E '^ExecStart'

Use the absolute path from that output in every step below.

2. Check the file exists and is executable.

ls -l /opt/myapp/bin/myapp

You want -rwxr-xr-x. Files on /tmp, /home, or a mounted data disk are common culprits.

3. Make it executable, if it is not.

chmod +x /opt/myapp/bin/myapp

4. Check the shebang of scripts.

A shell or Python script must start with a valid interpreter:

head -1 /opt/myapp/bin/myapp

#!/usr/bin/env python3 breaks when python3 is not on PATH; use the absolute interpreter path in that case.

5. Check the mount for noexec.

findmnt -no TARGET,OPTIONS /opt

If noexec appears, move the binary to a directory that allows execution, or remount without it.

6. Test SELinux if it is enforcing.

getenforce
sudo ausearch -m avc -ts recent

If there are denials for the binary, fix the context instead of disabling SELinux:

sudo restorecon -Rv /opt/myapp

7. Reload the unit after any edit.

sudo systemctl daemon-reload
sudo systemctl restart myapp

Verify

systemctl status myapp --no-pager
journalctl -u myapp -n 50 --no-pager

A healthy start shows Active: active (running) and your application’s own log lines.