How to Test Unit Conditions and Assertions in Ubuntu Using systemd-analyze condition

When developing custom system services, timers, or infrastructure automation scripts on Ubuntu, administrators frequently configure conditional execution rules inside systemd unit files. Directives such as ConditionPathExists=, ConditionVirtualization=, ConditionArchitecture=, and ConditionHost= allow units to execute only when specific hardware, file, or environment requirements are met. When these prerequisites are not satisfied, systemd skips unit execution cleanly without registering a service failure.

However, when a service fails to start or remains inactive following a boot cycle or daemon reload, determining whether the unit failed due to an execution error or was deliberately bypassed by a conditional directive can be challenging. Rather than parsing through thousands of journal entries, Ubuntu provides a dedicated diagnostic command: systemd-analyze condition. This tool evaluates all unit conditions and assertions directly against the active runtime environment, providing instant verification of why a service was executed or skipped.

Understanding systemd Conditions versus Assertions

The systemd unit file specification distinguishes between two types of environmental tests placed in the [Unit] section:

  • Conditions (Condition*=): Evaluates whether the unit should run. If any condition evaluates to false, systemd bypasses the unit entirely. The service transitions to an inactive state without logging an error, and downstream units depending on it proceed normally unless specifically configured otherwise.
  • Assertions (Assert*=): Evaluates mandatory prerequisites. If an assertion fails, the unit aborts immediately, transitions into a failed state, and logs a critical error to the systemd journal. This prevents services from attempting to run in broken or unsupported environments.

Common condition directives include file checks (ConditionPathExists=, ConditionFileNotEmpty=), container and hypervisor detection (ConditionVirtualization=), network state (ConditionNetworkOnline=), and kernel command-line arguments (ConditionKernelCommandLine=).

Evaluating Individual Conditions from the Terminal

You can test condition logic interactively from the command line before writing or modifying unit files. Pass any valid condition directive string directly to systemd-analyze condition:

# Test whether a configuration file exists
systemd-analyze condition 'ConditionPathExists=/etc/nginx/nginx.conf'

# Test whether a directory exists
systemd-analyze condition 'ConditionPathIsDirectory=/var/log/custom-app'

The command returns a structured assessment indicating whether the condition evaluates to true or false, accompanied by a symbol indicator (+ for true, - for false):

test: ConditionPathExists=/etc/nginx/nginx.conf succeeded.
+ ConditionPathExists=/etc/nginx/nginx.conf

If the path does not exist, the tool outputs a negative result:

test: ConditionPathExists=/etc/missing.conf failed.
- ConditionPathExists=/etc/missing.conf

You can also test environmental and architectural conditions across physical servers and virtual machines:

# Check if the host is running inside a virtual machine or container
systemd-analyze condition 'ConditionVirtualization=vm'

# Check if the system architecture matches x86-64
systemd-analyze condition 'ConditionArchitecture=x86-64'

# Check if AC power is currently connected (useful for backup jobs)
systemd-analyze condition 'ConditionACPower=true'

Testing Conditions Across Complete Service Units

Rather than testing individual strings, you can evaluate every condition and assertion defined inside an existing service unit or custom template:

# Evaluate conditions for a system service
systemd-analyze condition systemd-resolved.service

To test a custom service located in /etc/systemd/system/ or a newly drafted unit file before enabling it:

# Evaluate conditions defined in a custom backup service
systemd-analyze condition backup-database.service

The output lists every condition directive declared in the unit, its evaluated truth value, and whether the overall unit execution would proceed:

+ ConditionPathExists=/usr/local/bin/backup-script.sh
+ ConditionVirtualization=none
- ConditionPathExists=/mnt/backup-storage/active
failed

In this example, because /mnt/backup-storage/active is not mounted, the condition evaluated to false, causing the entire unit condition check to fail. This immediately explains why the backup service was skipped during scheduled execution.

Testing Negated Conditions and Prefix Modifiers

Systemd supports condition modifiers such as exclamation marks (!) for logical negation and pipe symbols (|) for logical OR conditions:

# Test negated condition (succeeds if path DOES NOT exist)
systemd-analyze condition 'ConditionPathExists=!/var/run/maintenance.lock'

When multiple conditions are prefixed with a pipe symbol (|), systemd treats them as an OR expression. If at least one condition marked with | evaluates to true, the condition block succeeds:

# Test multi-path condition with OR logic
systemd-analyze condition '|ConditionPathExists=/etc/app.conf' '|ConditionPathExists=/etc/app.d/default.conf'

Validating Assertions for Mission-Critical Units

When authoring mission-critical system daemons where silent skips are dangerous, assertions guarantee hard failure if prerequisites are unmet. Test assertion logic using Assert*= syntax:

# Test mandatory storage path assertion
systemd-analyze condition 'AssertPathIsDirectory=/data/storage'

# Test kernel command-line parameter assertion
systemd-analyze condition 'AssertKernelCommandLine=audit=1'

By using systemd-analyze condition during unit development and troubleshooting, administrators on Ubuntu can instantly identify prerequisite failures, test complex conditional expressions, and ensure reliable service orchestration across all deployment environments.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.