Linux Error Guide: 'Failed to start foo.service: Unit foo.service not found.' — Reload and fix the unit path
A practical walkthrough of why systemd reports a unit as not found, covering install paths, daemon-reload, template units, masking, and the exact fixes.
- #linux
- #troubleshooting
- #errors
- #systemd
Stuck on this Linux Admins error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
You try to start a service and systemd flatly refuses, telling you it has never heard of the unit you just wrote:
Failed to start foo.service: Unit foo.service not found.
This message means the systemd manager could not locate a loadable unit named foo.service anywhere in its unit search path, or the unit exists but is in a state (such as masked) that prevents it from being resolved. It is almost never a bug in systemd itself. In practice it is one of a small handful of causes: the unit file is not where systemd looks, systemd’s in-memory view of units is stale, the name has a typo, you dropped the .service suffix, or you are trying to start a template unit without an instance name.
The good news is that this class of failure is fully diagnosable with read-only commands before you change anything. This guide walks through the symptoms, the common root causes, and a repeatable diagnostic workflow so you can go from “not found” to a running service quickly and without guesswork.
Symptoms
systemctl start foo(orsystemctl restart foo,enable,status) returnsUnit foo.service not found.systemctl status fooshowsLoaded: not-found (Reason: Unit foo.service not found.)or, on older releases,Loaded: not-found (Reason: No such file or directory).- Tab-completion of the unit name in the shell does not offer
foo. - The service worked before a rename, a package reinstall, or a move of the unit file, and now cannot be started.
- A freshly created
/etc/systemd/system/foo.servicestill reports not-found until systemd is told to reload.
Common Root Causes
-
Unit file not installed or in the wrong path. systemd only reads units from its search path. For system units that is primarily
/etc/systemd/system(administrator overrides),/run/systemd/system(runtime), and/usr/lib/systemd/system(packages, sometimes/lib/systemd/system). A unit dropped in your home directory or/optwill not be seen. -
systemd has not reloaded. systemd caches the unit catalog in memory. After you add or edit a unit file on disk, the manager will not notice it until you run
systemctl daemon-reload. -
Typo in the unit name.
foo.serivce,Foo.service, or a trailing space produces a name that does not match the file. Unit names are case-sensitive. -
Missing
.servicesuffix confusion.systemctl start foois normally fine because systemctl assumes.service, but if your file is actuallyfoo.targetorfoo.timer, the implicit.servicelookup fails. -
User vs system scope. A unit installed under
~/.config/systemd/user/is a user unit and is invisible to the system manager. You must usesystemctl --user start foo, and vice versa. -
Template unit needs an instance. A file named
foo@.serviceis a template. You cannot startfoo@directly. You start an instance such asfoo@bar.service, wherebaris passed to the unit as%i. -
Masked unit. A masked unit is symlinked to
/dev/nulland deliberately unstartable. Masking can also surface as a not-found-adjacent refusal depending on the systemd version.
Diagnostic Workflow
Start with the unit’s own view of itself. status and cat tell you whether systemd can see the file at all and where it thinks the file lives.
systemctl status foo
systemctl cat foo
If cat prints the unit contents, the file is found and the problem is elsewhere (likely masking or an instance name). If it errors with “No files found for foo.service”, systemd genuinely cannot locate it.
List every unit file systemd currently knows about and filter for your name. This is the authoritative catalog:
systemctl list-unit-files | grep foo
If the file is on disk but not in that list, systemd has not reloaded its catalog. Force a reload and try again:
sudo systemctl daemon-reload
systemctl list-unit-files | grep foo
Confirm the file actually exists in a directory systemd reads, and check its exact name and suffix:
ls -l /etc/systemd/system/
ls -l /usr/lib/systemd/system/ | grep foo
Validate the unit’s syntax and references without starting it. systemd-analyze verify parses the file the same way the manager does and reports typos in directives or bad dependencies:
systemd-analyze verify /etc/systemd/system/foo.service
Check whether the unit is masked or in an unusual enable state:
systemctl is-enabled foo
systemctl is-active foo
If is-enabled returns masked, unmask it:
sudo systemctl unmask foo
sudo systemctl daemon-reload
Finally, if the unit did load but later failed, its logs live in the journal:
journalctl -u foo -b --no-pager
For a user-scoped unit, mirror the same commands with the --user flag:
systemctl --user daemon-reload
systemctl --user status foo
Example Root Cause Analysis
An engineer wrote a small worker service. They created the file, ran sudo systemctl start dataworker, and got Failed to start dataworker.service: Unit dataworker.service not found.
First check:
systemctl cat dataworker
# No files found for dataworker.service.
So systemd cannot see it. They confirm the file exists:
ls -l /etc/systemd/system/ | grep dataworker
# -rw-r--r-- 1 root root 412 Jul 7 09:14 dataworker.service
The file is present in the correct directory, which points squarely at a stale catalog. They reload and retry:
sudo systemctl daemon-reload
systemctl list-unit-files | grep dataworker
# dataworker.service disabled enabled
Now the unit appears. systemctl start dataworker succeeds. The root cause was simply that the unit was created after systemd had built its in-memory catalog, and no daemon-reload had been issued. Had the file instead lived in /opt/dataworker/dataworker.service, no reload would have helped, because that path is outside the search path; the fix there is to move or symlink the file into /etc/systemd/system/.
Prevention Best Practices
- Always
daemon-reloadafter touching unit files. Make it a reflex: edit the file, thensudo systemctl daemon-reload, then start. - Prefer
systemctl editfor overrides.systemctl edit foocreates drop-ins in the right directory and reloads for you, removing path mistakes entirely. - Validate before deploying. Run
systemd-analyze verify /path/to/unit.servicein CI or before enabling a unit, so typos in directive names are caught early. - Be explicit about scope. Decide up front whether a workload is a system unit or a user unit, and document which
systemctlinvocation operators should use. - Name template instances clearly. If you use
foo@.service, document the expected instance names and enable them explicitly, e.g.systemctl enable foo@production.service. - Avoid masking as a quick fix. If you mask a unit to silence it, record it, because a masked unit can baffle the next person who tries to start it.
Quick Command Reference
# See what systemd thinks of the unit
systemctl status foo
systemctl cat foo
systemctl is-enabled foo
# Is the unit in systemd's catalog?
systemctl list-unit-files | grep foo
# Pick up new or edited unit files
sudo systemctl daemon-reload
# Confirm the file exists in a search path
ls -l /etc/systemd/system/
ls -l /usr/lib/systemd/system/ | grep foo
# Validate syntax without starting
systemd-analyze verify /etc/systemd/system/foo.service
# Unmask a deliberately disabled unit
sudo systemctl unmask foo
# Start a template instance, not the template
sudo systemctl start foo@bar.service
# User-scoped units
systemctl --user daemon-reload
systemctl --user status foo
# Read the logs
journalctl -u foo -b --no-pager
Conclusion
Unit foo.service not found. is systemd telling you it cannot resolve the name you gave it to a loadable file in its search path. Work the problem in order: ask systemd what it sees with systemctl cat and list-unit-files, reload the catalog with daemon-reload, confirm the file is in /etc/systemd/system or /usr/lib/systemd/system, verify the exact name and suffix, and check for masking or a template that needs an instance. Because every step is a read-only inspection until the final fix, you can diagnose this confidently without risking further breakage, and the same workflow applies whether the unit is system-scoped or user-scoped.
Fixed it? Get 500 Linux Admins & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.