The ExecStart directive in your systemd unit file is failing because the path to the executable it’s trying to run is incorrect, leading the system to believe the command simply doesn’t exist.
This is a common issue when dealing with custom services or when system updates might have shifted executable locations. The core problem is that systemd, when instructed to start a service via ExecStart=/path/to/executable, performs a lookup for /path/to/executable. If it doesn’t find a file at that exact path, or if the file isn’t executable by the user systemd is running as, it bails out with a "not found" error, even if the executable is present elsewhere or has permission issues.
Here’s a rundown of the most frequent culprits and how to fix them:
1. Typo in the ExecStart Path:
This is the most straightforward, yet surprisingly common, error. A single misplaced character, a missing slash, or an incorrect directory name will cause the lookup to fail.
- Diagnosis: Manually attempt to execute the command as specified in your
ExecStartline. For example, if your unit file hasExecStart=/usr/local/bin/my-app, try runningsudo -u <user_running_service> /usr/local/bin/my-app(replace<user_running_service>with the user specified inUser=orsystemd’s default if none is set). Also, runls -l /usr/local/bin/my-appto verify its existence. - Fix: Carefully re-examine your unit file and compare the
ExecStartpath character by character with the actual location of your executable. Correct any discrepancies. For instance, changeExecStart=/usr/local/bin/my-apptoExecStart=/usr/local/bin/my-appif you found a typo. - Why it works: Ensures systemd is pointing to the exact, correct file.
2. Executable Not in Systemd’s PATH (and not an absolute path):
If your ExecStart directive uses a command name without a leading slash (e.g., ExecStart=my-app), systemd will try to find my-app in its PATH environment variable. This PATH is often minimal for security reasons, especially for services.
- Diagnosis: Check the
PATHenvironment variable that systemd is using. You can get a sense of this by creating a temporary unit file that just prints thePATH:
Then[Unit] Description=Print PATH [Service] Type=oneshot ExecStart=/bin/sh -c 'echo $PATH' [Install] WantedBy=multi-user.targetsudo systemctl daemon-reload,sudo systemctl start print-path.service, andsudo journalctl -u print-path.service. Compare thisPATHto where your executable is located. - Fix: Always use the absolute path to your executable in
ExecStart. For example, ifmy-appis located at/opt/my-app/bin/my-app, change your directive toExecStart=/opt/my-app/bin/my-app. - Why it works: Explicitly telling systemd the full path bypasses the need for it to search through its limited
PATHenvironment.
3. Permissions Issues: The executable file might exist, but the user systemd is trying to run the service as doesn’t have execute permissions for it.
- Diagnosis: First, identify the user the service runs as. Check the
User=directive in your unit file. If it’s not set, systemd defaults toroot. Then, check the permissions of the executable:ls -l /path/to/your/executable. - Fix: Grant execute permissions to the appropriate user or group. If the service runs as
myuserand the executable is/opt/my-app/bin/my-appand owned byroot:root, you might use:sudo chown myuser:myuser /opt/my-app/bin/my-apporsudo chmod u+x /opt/my-app/bin/my-appifmyuseris the owner, orsudo chmod +x /opt/my-app/bin/my-appif execute permission for 'others' is sufficient (be cautious with this). A common scenario is making it executable for the group the user belongs to. - Why it works: Ensures the user specified in the unit file has the necessary rights to execute the program.
4. Executable Moved or Deleted by a Package Manager/Update: System updates can sometimes relocate executables or remove them if a package is upgraded or replaced.
- Diagnosis: Use
findto locate the executable across your filesystem. For example:sudo find / -name my-app -type f 2>/dev/null. This will search for files namedmy-appstarting from the root directory. - Fix: Once located, update your
ExecStartdirective with the new, correct path found byfind. If the executable was removed and replaced by a newer version in a different location, update yourExecStartaccordingly. - Why it works: Points systemd to the executable’s current, valid location.
5. Incorrectly Specified Interpreter (for scripts):
If ExecStart points to a script (e.g., a Python or Bash script), and the shebang line (#!/usr/bin/env python3 or #!/bin/bash) is incorrect or the interpreter itself isn’t found, systemd might report the script as "not found" because it can’t execute it.
- Diagnosis: Check the shebang line at the very top of your script. Verify that the interpreter specified (e.g.,
/usr/bin/python3) actually exists and is executable. Try running the script directly from the command line:/path/to/your/script.sh. - Fix: Correct the shebang line to point to the correct interpreter path. If
#!/usr/bin/python3fails, but#!/usr/bin/env python3works, use that. Ensure the interpreter binary itself is correctly installed and accessible. - Why it works: Systemd, or the shell it invokes, needs to find the interpreter to run the script.
6. Incorrect Working Directory (WorkingDirectory=):
While not directly causing an "ExecStart not found" error, an incorrect WorkingDirectory= combined with a relative path in ExecStart could lead to this if the script/program expects to be run from a specific directory and uses relative paths internally for its own dependencies or executables. However, the primary "not found" error usually stems from the ExecStart path itself.
- Diagnosis: Review your
WorkingDirectory=directive. Ensure it’s set to a valid, existing directory. - Fix: Correct the
WorkingDirectory=path to the intended directory. - Why it works: Ensures the service starts in the expected environment, allowing it to find its own resources if it relies on relative paths.
After fixing your unit file, remember to always run sudo systemctl daemon-reload to make systemd re-read the configuration files, and then sudo systemctl restart your-service-name.service to apply the changes.
The next error you’ll likely encounter if this was the only issue is a "permission denied" error from the executed program, or a specific error message from the application itself indicating missing configuration files or dependencies.