Preflight

Validate a host and agent configuration before unbounded-agent bootstrap.

unbounded-agent preflight validates that a host and the loaded agent configuration are ready for bootstrap before the agent mutates host state or joins the cluster. It loads the same config used by unbounded-agent start, resolves the expected nspawn rootfs and download inputs, and runs non-mutating checks against the host, cluster API server, artifact sources, and GPU driver state.

Preflight is safe to run repeatedly before bootstrap and after failed bootstrap attempts. It is expected to run as a privileged user on the host because several checks need direct access to host systemd, kernel, filesystem, and device state.

Usage

Run preflight on the target host:

unbounded-agent preflight --config /etc/unbounded/agent.json

If --config is omitted, the agent uses the same config loading behavior as unbounded-agent start, including the UNBOUNDED_AGENT_CONFIG_FILE environment variable.

UNBOUNDED_AGENT_CONFIG_FILE=/etc/unbounded/agent.json \
  unbounded-agent preflight

Preflight does not install packages, pull the rootfs image, download full binary artifacts, create the nspawn machine, start kubelet, or join the cluster.

Generated install and bootstrap scripts run preflight by default before unbounded-agent start. Set AGENT_PREFLIGHT=false in the target host environment to skip that automatic preflight step.

Flags

FlagDescription
--configPath to the agent config file. When omitted, the agent uses its normal config loading behavior.
--ignore-preflight-errorsComma-separated check names whose errors should be reported as warnings. Use all to ignore all fatal checks.
--fail-on-warningsExit non-zero when any warning is returned, even if there are no fatal errors.
--outputOutput format. Supported values are text and json. Default: text.

The generated install script also honors AGENT_PREFLIGHT. It defaults to running preflight. Set AGENT_PREFLIGHT=0, AGENT_PREFLIGHT=false, or AGENT_PREFLIGHT=no to skip preflight before unbounded-agent start.

Examples:

unbounded-agent preflight --config /etc/unbounded/agent.json
unbounded-agent preflight --ignore-preflight-errors=swap-active
unbounded-agent preflight --ignore-preflight-errors=nvidia-driver
unbounded-agent preflight --ignore-preflight-errors=all
unbounded-agent preflight --fail-on-warnings
unbounded-agent preflight --output json > preflight-report.json

Exit Behavior

Warnings do not fail the command by default. Errors are fatal unless they are ignored with --ignore-preflight-errors.

ResultExit code
No fatal errors and --fail-on-warnings is not set0
One or more fatal errors remainNon-zero
One or more warnings exist and --fail-on-warnings is setNon-zero

Ignored errors are downgraded to warnings in the report. If --fail-on-warnings is set, ignored errors still cause a non-zero exit because they are warnings.

Text Output

Text output is intended for humans and follows a kubeadm-style format:

[preflight] Running unbounded-agent pre-flight checks
    [OK is-privileged-user]: preflight is running as root (target: host user)
    [WARNING swap-active]: swap is enabled and bootstrap will disable it (target: host swap)
[preflight] Some fatal errors occurred:
    [ERROR oci-image-reachable]: rootfs image source is not reachable: rootfs-image (target: rootfs image)
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`

Successful checks and warnings are printed as check results. Fatal errors are summarized at the end.

JSON Output

JSON output contains every result, including successful checks, warnings, ignored errors, and fatal errors:

{
  "status": "failed",
  "checks": [
    {
      "name": "is-privileged-user",
      "target": "host user",
      "severity": "ok",
      "message": "preflight is running as root",
      "ignored": false
    },
    {
      "name": "swap-active",
      "target": "host swap",
      "severity": "warning",
      "message": "swap is enabled and bootstrap will disable it",
      "ignored": false
    },
    {
      "name": "oci-image-reachable",
      "target": "rootfs image",
      "severity": "error",
      "message": "rootfs image source is not reachable: rootfs-image",
      "ignored": false
    }
  ],
  "summary": {
    "ok": 1,
    "warnings": 1,
    "errors": 1
  }
}

The status field is ok when the command would exit successfully and failed when fatal errors remain or --fail-on-warnings makes warnings fail.

Config Loading and Goal Resolution

Before running the named checks below, the command loads the agent config, validates it, and resolves the machine goal state used by bootstrap. Failures at this stage are returned as command errors before a preflight report is printed. For example, invalid JSON, missing required config fields, invalid bootstrap authentication, unsupported download settings, or an unresolvable rootfs goal state can stop the command before check output is produced.

Current Checks

After config loading and goal resolution succeed, the current preflight check set is organized around the same bootstrap phases as unbounded-agent start.

Host Checks

CheckSeverity when failingWhat it validates
is-privileged-userErrorPreflight is running as root. Bootstrap requires root privileges.
host-packagesError or warningA supported package manager is available (apt-get, tdnf, or dnf) and required host packages are installed. Missing package manager support is fatal. Missing packages are warnings because bootstrap may install them.
host-os-configurationErrorHost OS configuration paths are writable, including the sysctl config directory and systemd unit directory.
nspawn-runtimeWarningRequired nspawn runtime tools are available: systemctl, machinectl, and systemd-nspawn. It also checks that /run/systemd/system is available. Missing tools are warnings because bootstrap may install them.
docker-activeWarningDocker is active. Bootstrap will disable Docker when needed.
swap-activeWarningSwap is active or swap state cannot be determined. Bootstrap will disable active swap.
disk-spaceErrorAt least 8 GiB is available under /var/lib for machine rootfs and artifacts.
cgroupsErrorThe cgroup filesystem exists at /sys/fs/cgroup.
nvidia-driverError or warningIf NVIDIA GPU hardware or device nodes are detected, validates the host NVIDIA driver stack. Hosts without NVIDIA GPUs pass this check.

The nvidia-driver check can return multiple results with different targets:

TargetSeverity when failingWhat it validates
NVIDIA PCI hardwareOKNVIDIA PCI devices were detected.
NVIDIA PCI driverError or warningNVIDIA PCI devices are bound to the nvidia kernel driver. Device nodes without matching PCI hardware are reported as a warning.
NVIDIA kernel modulesError or warningRequired modules are loaded: nvidia, nvidia_modeset, nvidia_uvm, and nvidia_drm. Missing modules are errors. An unknown module version is a warning.
NVIDIA device nodesError or warningRequired device nodes exist, including /dev/nvidiactl, /dev/nvidia-uvm, and at least one /dev/nvidia<N> GPU node. Missing required nodes are errors. Missing UVM tools, capability, or DRI render nodes are warnings.
NVIDIA driver librariesErrorldconfig can discover required host driver libraries for the host architecture, including libcuda.so.1 and libnvidia-ml.so.1.
NVIDIA diagnostic toolingError or warningnvidia-smi -L can query GPUs. Missing nvidia-smi is a warning. A failed or empty query is an error.
NVIDIA persistence serviceWarningnvidia-persistence-mode.service is installed and active when systemd is available.

Cluster API Check

CheckSeverity when failingWhat it validates
api-server-reachableErrorCluster CA data and bootstrap credentials are valid enough to use, the configured API server endpoint is well formed, and the host can reach the API server /readyz endpoint. API server responses with status 500 or higher are fatal.

Rootfs and Artifact Checks

CheckSeverity when failingWhat it validates
oci-image-reachableErrorThe selected rootfs OCI image is configured and its registry manifest, local layout, or HTTPS layout archive is reachable without pulling image contents.
kubernetes-artifactsErrorRequired Kubernetes binary sources are reachable without downloading full artifacts: kubelet, kubectl, and kube-proxy.
cri-artifactsErrorRequired CRI artifact sources are reachable without downloading or extracting full artifacts: containerd, runc, and crictl.
cni-artifactsErrorThe CNI plugins artifact source is reachable without downloading or extracting the full artifact.
nspawn-machine-provisioningError or warningThe nspawn machine directory and provisioning paths are usable. Invalid or unreadable paths are fatal. Existing machine directory permissions that are too restrictive are warnings.

HTTP artifact checks probe each resolved URL without downloading the full artifact. OCI registry checks resolve the image manifest without pulling layers; HTTPS archive checks probe the archive URL without downloading it.

Sensitive Values

Preflight output must not be treated as a dump of agent configuration. The report uses logical targets such as cluster API server, bootstrap credentials, rootfs image, and kubernetes artifacts instead of raw tokens, certificate data, URLs, image references, or file contents.