| Tested on | Red Hat Enterprise Linux 10.2 (Coughlan) |
|---|---|
| Package | podman-5.8.2-5.el10_2.x86_64 |
| Applies to | Any Linux host with Podman 4.6+ and systemd |
| Privilege | sudo for rootful examples; normal user with systemctl --user for rootless checks |
| Scope | Layered Quadlet debugging — unit not found, search paths, generator dry-run, QUADLET_UNIT_DIRS, unsupported directives, systemd-analyze verify, mandatory daemon-reload, SourcePath, generated-unit warnings, journal reading, oneshot semantics, boot enablement signals, and rootless linger routing. Absorbs unit-not-found recovery. Does not reteach enable mechanics, .pod restart traps, volume permissions, network fixes, or rootless setup. |
| Related guides | Podman Quadlet CLI |
Your Quadlet source file exists, but systemctl start says the unit is missing — or the service starts and immediately fails with no obvious container. Before you reach for podman logs, decide which layer broke. Generator, systemd, and Podman each fail differently, and fixing the wrong layer wastes time.
Start by identifying which layer failed
Walk the stack from source file to running container:
Quadlet source on disk?
│
▼
Generator parsed it?
│
▼
.service unit generated?
│
▼
systemd loaded the service?
│
▼
Podman command succeeded?
│
▼
Container or resource healthy?If no .service was generated, podman logs cannot help — nothing reached Podman yet. If the unit exists but ExecStart fails, journal and manual podman run checks belong on this page. Deeper runtime topics (ports, volumes, networks) have dedicated guides linked inline.
Error: Unit ... service not found
This is the signature failure when systemd has no web.service in the active manager.
Try to start it:
sudo systemctl start web.serviceSample output:
Failed to start web.service: Unit web.service not found.Rootless users see the same wording under the user manager:
systemctl --user start web.serviceWork through the checks below before assuming Podman is broken.
Is the Quadlet in a valid search path?
Rootful units belong under:
/etc/containers/systemd/Rootless units belong under the owning user's config tree:
~/.config/containers/systemd/Administrators may also place user units under /etc/containers/systemd/users/ or /etc/containers/systemd/users/${UID}/. See Rootless Podman Quadlet for path detail — this page only verifies the file is where the generator expects it.
Is the extension correct?
Available Quadlet types depend on Podman version. Podman 5.8.2 recognizes typed suffixes such as:
web.container
app.kube
app.pod
data.volume
app.network
web.build
base.image
data.artifactOlder Podman releases may not support every suffix — .build, .pod, and especially .artifact arrived in later versions. A file named web.service or web.txt in the directory will not produce a Quadlet unit.
Did you reload systemd?
After adding or moving a Quadlet file:
sudo systemctl daemon-reloadRootless:
systemctl --user daemon-reloadWithout reload, systemd may never invoke the Podman generator for the new source.
Did the generator reject the file?
When path, extension, and reload look correct but the unit is still missing, run the generator directly — covered in the next section.
Find the generator binary on your host
Paths vary by distribution packaging. Discover what your podman RPM installed:
rpm -ql podman | grep -E 'quadlet|generator'On RHEL 10.2 the lab host exposes:
/usr/libexec/podman/quadlet
/usr/lib/systemd/system-generators/podman-system-generator
/usr/lib/systemd/user-generators/podman-user-generatorpodman-system-generator and podman-user-generator are symlinks to /usr/libexec/podman/quadlet. Upstream documentation often shows the generator path under system-generators; on this build the real binary is /usr/libexec/podman/quadlet.
Confirm flags:
/usr/libexec/podman/quadlet --helpSample output:
-dryrun
Run in dryrun mode printing debug information
-user
Run as systemd userUse that binary for the dry-run examples below.
Run the Quadlet generator manually
Dry-run prints translated units without touching systemd. For rootful debugging:
/usr/libexec/podman/quadlet -dryrunRootless generator logic:
/usr/libexec/podman/quadlet -user -dryrunA healthy single-unit source produces a ---web.service--- block and an ExecStart= line you can read immediately.
Isolate sources with QUADLET_UNIT_DIRS
System-wide dry-run noise from dozens of installed units makes one bad file hard to spot. Copy only the suspect Quadlet into a clean directory:
mkdir /tmp/quadlet-debug
cp web.container /tmp/quadlet-debug/Run the generator against that directory alone:
QUADLET_UNIT_DIRS=/tmp/quadlet-debug /usr/libexec/podman/quadlet -dryrunSample output:
quadlet-generator[252717]: Loading source unit file /tmp/quadlet-debug/web.container
---web.service---
[X-Container]
Image=quay.io/podman/hello
ContainerName=debug-hello
...
ExecStart=/usr/bin/podman run --name debug-hello ...Rootless:
QUADLET_UNIT_DIRS=/tmp/quadlet-debug /usr/libexec/podman/quadlet -user -dryrunQUADLET_UNIT_DIRS is one of the fastest ways to prove whether a single source file parses — without unrelated generator errors from other Quadlets on the host.
Detect unsupported directives from a newer Podman
A .container copied from Podman 6 docs may reference keys your installed generator does not understand. Add a deliberate bad key to see the error shape:
[Container]
Image=quay.io/podman/hello
UnsupportedDirective=fooDry-run:
QUADLET_UNIT_DIRS=/tmp/quadlet-debug /usr/libexec/podman/quadlet -dryrunSample output:
quadlet-generator[252952]: converting "bad.container": unsupported key 'UnsupportedDirective' in group 'Container' in /tmp/quadlet-debug/bad.container
quadlet-generator[252952]: processing encountered some errorsThe generator may still emit other valid units in the same run, but the named file will not produce a service. Check your package before blaming a typo:
podman --versionSample output:
podman version 5.8.2Version skew is a common reason a unit never appears — especially when playbooks pin an older Podman on the host but pull unit files from newer documentation.
Use systemd-analyze verify
Generator dry-run answers Quadlet translation. systemd-analyze verify answers whether the generated systemd unit is structurally valid once generators have run.
After daemon-reload, verify the generated unit file path:
systemd-analyze verify /run/systemd/generator/web.serviceA clean check exits silently on the lab host. Rootless:
systemd-analyze --user --generators=true verify /run/user/1014/systemd/generator/web.serviceYou can also enable generators during verify:
systemd-analyze --generators=true verify web.service| Tool | Finds |
|---|---|
quadlet -dryrun |
Bad Quadlet keys, missing sections, unsupported types |
systemd-analyze verify |
Invalid unit syntax, broken dependencies in the generated .service |
Use both when a unit fails to load or start.
Reload systemd after every Quadlet change
A recurring mistake: edit web.container, then immediately:
sudo systemctl restart web.servicewithout reloading. systemd warns when the source changed on disk:
Warning: The unit file, source configuration file or drop-ins of web.service changed on disk. Run 'systemctl daemon-reload' to reload units.The loaded ExecStart may still reference the old container name until you reload. Correct workflow:
sudo systemctl daemon-reload
sudo systemctl restart web.serviceRootless:
systemctl --user daemon-reload
systemctl --user restart web.serviceDo not rely on reboot during normal editing — reload is the routine step.
Find the source Quadlet for a generated service
When several similarly named units exist, ask systemd which source file produced the unit:
systemctl show -p SourcePath web.serviceSample output:
SourcePath=/etc/containers/systemd/web.containerRootless:
systemctl --user show -p SourcePath web.serviceSample output:
SourcePath=/home/podtest/.config/containers/systemd/web.containerCompare with the generated unit:
systemctl cat web.serviceSample output:
# /run/systemd/generator/web.service
# Automatically generated by /usr/lib/systemd/system-generators/podman-system-generator
[X-Container]
Image=quay.io/podman/hello
...
ExecStart=/usr/bin/podman run --name debug-hello-v2 ...SourcePath points at the editable Quadlet. systemctl cat shows the generated service including [Unit] wiring — never edit files under /run/systemd/generator/ or /run/user/.../systemd/generator/ directly.
Never edit the generated .service
Generator output is ephemeral. Changes under:
/run/systemd/generator/
/run/user/$UID/systemd/generator/disappear on the next daemon-reload. Fix the Quadlet source (*.container, *.pod, *.volume, …) or add a systemd drop-in, then reload.
Read systemd service errors
Once a unit exists, start with status:
systemctl status web.service --no-pagerSample output:
● web.service
Loaded: loaded (/etc/containers/systemd/web.container; generated)
Active: active (running) since Sun 2026-08-23 03:30:09 IST; 43ms ago
Main PID: 253435 (conmon)Pull the journal for this boot:
journalctl -u web.service -b --no-pager -n 8Rootless status uses the user manager:
systemctl --user status web.service --no-pagerUser-scoped journal for the same unit:
journalctl --user -u web.service --no-pager -n 8Read the log for the failure class:
- image pull errors or registry timeouts
- port already allocated
- mount or permission denied on volumes
- executable exited immediately
- start job timed out
Route port and volume failures to Podman port mapping and volume permission guides when the journal names those resources.
Generated service exists but no container appears
Inspect what systemd actually runs:
systemctl show -p ExecStart web.serviceSample output:
ExecStart={ path=/usr/bin/podman ; argv[]=/usr/bin/podman run --name debug-hello-v2 --replace --rm ... ; ... }Copy the podman run arguments into a manual test only to isolate the failure — do not leave a bypass script in production. If ExecStart never ran, the problem is still systemd ordering or timeouts, not Podman runtime.
Service times out while pulling an image
A .container or .kube service can exceed systemd's normal startup timeout while Podman pulls or builds an image. Raise TimeoutStartSec= in [Service] or pre-pull the image. Resource Quadlets such as .build and .image are oneshot units on Podman 5.8.2 and do not use the same default startup-timeout behavior.
[Service]
TimeoutStartSec=900Or pre-pull the image before enabling the unit. The journal usually shows pull progress stopping mid-stream when timeout is the culprit.
Service is inactive (dead) but the resource exists
Oneshot Quadlet types — .volume, .network, .build, .image, .artifact — often finish prep work and exit.
Start a volume unit:
sudo systemctl start data-volume.serviceCheck status:
systemctl status data-volume.service --no-pagerSample output:
● data-volume.service
Loaded: loaded (/etc/containers/systemd/data.volume; generated)
Active: active (exited) since Sun 2026-08-23 03:30:27 IST; 32ms ago
Process: 253771 ExecStart=/usr/bin/podman volume create --ignore systemd-data (code=exited, status=0/SUCCESS)Verify the Podman object:
podman volume lsSample output:
local systemd-dataResource Quadlets are oneshot services, so they do not represent a continuously running process. Depending on the generated unit, you may see active (exited) or a completed/inactive state. Check Result=success, the command exit status, the journal, and whether the Podman resource exists before treating the state as a failure.
Quadlet service is not enabled at boot
Do not run:
systemctl enable web.serviceon a generated transient unit when enablement should come from the Quadlet source:
[Install]
WantedBy=multi-user.targetAfter adding or changing [Install], reload systemd. Full enable and target wiring lives in Podman Quadlet with systemd — here you only confirm the section exists before chasing generator errors.
Rootless boot persistence also needs linger — see Rootless Podman Quadlet rather than repeating setup on this page.
Container exists with unexpected systemd- name
List containers:
podman ps -a --format '{{.Names}}'Quadlet defaults to systemd-<unit> unless you set ContainerName= in the [Container] section. That naming is documented behavior, not a generator bug. Set ContainerName= when downstream scripts expect a fixed name — see Podman Quadlet container file.
Dependencies start in the wrong order
Inspect ordering:
systemctl list-dependencies web.service --no-pagerSample output:
web.service
● ├─network-online.target
● │ └─NetworkManager-wait-online.serviceRead generated After= and Requires= in:
systemctl cat web.serviceOrdering guarantees start sequence — not application readiness inside the container. Prefer HealthCmd, Notify=, or explicit After= on image or volume units instead of sleep in ExecStartPre.
Rootless unit works until logout
When a user unit stops after the last SSH session ends, linger is the usual cause. Check:
loginctl show-user podtest -p LingerSample output:
Linger=yesLinger=no means the user manager may disappear on logout. Full linger workflow: Rootless Podman Quadlet.
Debug checklist
Run top to bottom for a missing or failed unit. Add --user on every systemctl and journalctl command when debugging rootless Quadlet.
Check Podman version first:
podman --versionReload after any source edit:
sudo systemctl daemon-reloadInspect whether systemd knows the unit:
systemctl status web.service --no-pagerTrace back to the source file:
systemctl show -p SourcePath web.serviceRead the generated unit:
systemctl cat web.serviceTranslate Quadlet in isolation:
QUADLET_UNIT_DIRS=/tmp/quadlet-debug /usr/libexec/podman/quadlet -dryrunValidate generated systemd syntax:
systemd-analyze verify /run/systemd/generator/web.serviceRead service logs:
journalctl -u web.service -b --no-pager -n 20Confirm whether Podman created a container:
podman ps -aTroubleshooting matrix
| Symptom | Likely layer | First check |
|---|---|---|
Unit ... not found |
Generator or path | Search path, extension, daemon-reload, quadlet -dryrun |
unsupported key in dry-run |
Generator / version | podman --version, compare docs to installed Podman |
| Warning about unit changed on disk | systemd cache | daemon-reload before restart |
active (exited) on .volume |
Oneshot resource unit | Result=, journal exit status, podman volume ls |
Service start timeout on .container / .kube |
systemd / pull or build | Journal pull lines, raise TimeoutStartSec, pre-pull image |
| Wrong container name | Quadlet source | ContainerName= in .container |
| Works until logout | User session | loginctl show-user -p Linger |
References
- podman-systemd.unit(5) — Quadlet syntax and search paths
- Podman Quadlet documentation — install and management CLI
- systemd-analyze(1) — unit verification
- systemd.unit(5) — generated unit properties such as
SourcePath
Summary
Quadlet failures split cleanly across layers. When systemctl reports unit not found, the generator never produced a service — check path, extension, reload, then QUADLET_UNIT_DIRS with quadlet -dryrun before opening Podman logs. Unsupported keys and version skew show up directly in generator output; systemd-analyze verify catches problems in the translated unit after reload.
Once a unit exists, SourcePath and systemctl cat tie the running service back to the editable source. Reload after every edit — systemd keeps the old ExecStart until you do. Resource Quadlets are oneshot services; check Result=, exit status, the journal, and the Podman resource instead of expecting a long-running active state.
Rootless boot and logout issues route to Rootless Podman Quadlet. Enable mechanics and [Install] depth stay in Podman Quadlet with systemd. This page absorbs the old unit-not-found slug — bookmark it whenever a Quadlet source is on disk but the matching .service never appears.

