Watch at EaseStories. Answers. Perspective.

Technology · PRACTICAL GUIDE

systemd status=218/CAPABILITIES? Prove the manager, kernel and capability sets first

The application may not have run at all. Preserve the first journal error, read the effective unit, separate system, user and container boundaries, and change only the capability transition that evidence shows is invalid.

Original technical diagram: Capability failure boundary for systemd status=218/CAPABILITIES.
Original Watch at Ease illustration: locate the manager, kernel or container boundary before editing capabilities. Watch at Ease

status=218/CAPABILITIES is a systemd execution-stage failure: the manager could not drop capabilities or apply ambient capabilities before the service program ran. Application logs may therefore be absent or irrelevant.

Do not begin by deleting every hardening directive, running the daemon as root or granting CAP_SYS_ADMIN. Capture the exact failing step and prove which manager, namespace, kernel and capability set own it.

Freeze the first capability-stage evidence

Save systemctl status and the journal from the first failed invocation, including whether the message says failed to drop capabilities, apply ambient capabilities, or set up a namespace. Record systemctl versus systemctl --user.

Stop a rapid restart loop before it buries the first message. Capture FragmentPath, DropInPaths and the loaded manager so an inherited drop-in is not confused with the file you opened.

Read the effective unit and all capability controls

Read CapabilityBoundingSet=, AmbientCapabilities=, NoNewPrivileges=, SecureBits=, PrivateUsers= and related hardening from the merged unit. Record the service User= and executable but do not debug the application yet.

Compare requested capabilities with the sets systemd must construct. Ambient elevation depends on permitted and inheritable membership; the bounding set can prevent a requested capability from surviving.

Locate the manager, kernel and container boundary

Classify the execution domain: PID 1 system manager, a per-user manager, a container, or a host with an older kernel/systemd combination. Reproduce only in that same boundary.

For a user manager, verify unprivileged user-namespace support and the documented PrivateUsers= behavior. For a container, inspect the outer runtime policy and bounding set; the host can deny an operation the inner unit requests.

Repair one proved contradiction without broad privilege

Correct the single demonstrated mismatch: move the unit to the intended manager, remove one unsupported inherited directive, include the required capability in the compatible sets, update a proven incompatible kernel/package pair, or change the container policy through its owner.

Do not replace a narrow requirement with all capabilities or CAP_SYS_ADMIN. If the service no longer needs a capability, remove the request and document why; if it does, preserve the smallest set and the original identity boundary.

Start once, inspect the live sets and test real work

Reload the same manager only after a unit change, clear rate-limit state only if retries created it, and make one controlled start. Re-read the new journal before declaring success.

Inspect /proc/$PID/status or a trusted capability tool for permitted, effective, bounding and ambient sets. Then perform one real bind, tun/tap, clock or other operation that required the capability and confirm no unrelated privilege was added.

Original technical diagram: Minimal-change decision path for status=218/CAPABILITIES.
Original Watch at Ease illustration: change only the proved layer, then verify the live process and one real operation. Watch at Ease