Read dependencies as explicit contracts
After defines ordering among units involved in a transaction; it does not itself activate the other unit. A service needing /srv/ledger/data should declare appropriate mount requirements as well as ordering. RequiresMountsFor can add Requires and After for mounts needed by the path, with configuration and support checked. This does not replace validating the effective volume or data. The example uses systemd v258 documentation; check the installed version before copying options. An apparently data-related unit name does not prove it represents the required mount.
Handle writes to the wrong destination
If a service starts before its volume, it can write into the underlying directory on the root filesystem. Mounting over it can hide those writes without deleting or reconciling them. Stop work according to the approved plan, identify the actual destination, and preserve data needed for recovery. Correct the dependency and verify behavior after a controlled start. A fixed delay does not establish that the correct volume is available. Include what to observe when mounting fails in handover so RUN does not silently accept an alternative destination.
Distinguish startup, readiness, and retries
A Type=simple service can be active while the application still loads data. A dependent unit needs supported readiness or appropriate waiting and retry; changing to Type=notify without support does not produce READY=1. Likewise, Restart=on-failure does not guarantee recovery from invalid configuration. On start-limit-hit, fix the cause, confirm effective state, and reset the counter as needed before testing. Permanently removing limits may only prolong repeated failure. Final acceptance should include a useful application operation rather than only process state.
Identify who parses and opens the target
ExecStart does not automatically interpret > as shell redirection. Choose output configuration or a wrapper with explicit interpretation and controlled scope. In an interactive shell, sudo on a command also does not automatically elevate the opening performed by the shell for >. The process opening the destination needs appropriate authorization. Do not fix this by making a protected file world-writable. Distinguish manager-parsed syntax, program arguments, and files opened before execution. That sequence explains differences between a manual command and a service.
Capture statuses before replacing them
In Bash without pipefail, false | true returns zero because the last command succeeded. With pipefail, the earlier failure produces a nonzero status. PIPESTATUS exposes components, but another command can replace the array; save it immediately. The example below touches no files or services and can be exercised in an isolated shell. This expansion’s local checks use Bash 3.2 on macOS for these shell behaviors rather than a Linux lab. Applying it to a real job still requires examining traps, errexit, subprocesses, and how the scheduler receives results.
Confirm SSH configuration and address family
For options such as User, OpenSSH normally uses the first obtained value. Host * with User general before Host ledger with User batch can select general in the simple case without overrides. ssh -G helps inspect evaluated configuration but tests neither connection nor authentication. Also distinguish IPv6 listening from IPv4 coverage: a [::] socket explicitly using IPV6_V6ONLY=1 does not accept IPv4. Identify context, options, and family before changing firewalls. The exercises do not assume identical defaults across every system or version.
Accept complete business results
A compressor can produce a valid file containing only half the expected records. Propagating stage failures is necessary, but zero statuses do not prove completeness either. Define count, integrity, reconciliation, and publication conditions appropriate to the job. If validation fails, preserve partial output as evidence according to process and prevent it from being treated as a completed delivery. In international communication, separate process completed, file created, and export reconciled. These terms describe different states and prevent another team consuming incomplete data through an overbroad interpretation of success.
set -o pipefail
false | true
steps=("${PIPESTATUS[@]}")
printf 'first=%s last=%s\n' "${steps[0]}" "${steps[1]}"false | true returns 0 by default and 1 with pipefail. Neither outcome validates a business file’s record count.
Common pitfalls
After as activation, active as readiness, ExecStart as shell, ssh -G as authentication, or zero as completeness.
Related topics: Services and batch · SSH and network diagnosis
A recovered service needs the correct context and a verified useful outcome as well as a running process.
Reference: systemd.unit source manual · LFCS current five-domain outline; exact edition date unconfirmed