Skip to Content

Status & Doctor

ironflock status shows what of IronFlock is on a machine and whether it runs. ironflock doctor checks whether a machine can run the device agent and whether it reaches the hosts the agent talks to. Use them before you connect a machine, and when a device does not come online.

Both commands change nothing and ask nothing. They run on Linux and macOS, without root, and read more as root. With --host they run on another machine, also on several at once (Remote Machines over SSH). There they run as root when the login is root or may use sudo without a password and without a terminal; otherwise they run as the login, without asking, and their hint names the command with --host root@machine.

ironflock status

Shows the device agent, the appliance and the operating system of this machine: what is installed, its version, whether its service runs, the device and its project, and the agent’s last self-update. The appliance is the complete IronFlock system on a machine on site (IronFlock Appliance); for an appliance the command also shows the address of its UI, its license, the health of its services and an update that waits (Appliance Commands). On IronFlockOS the command also shows the root slots and what needs attention.

ironflock status [flags]

Runs on: Linux; on macOS it shows the system and that nothing is installed. Root: not required; a few facts need it. Asks: nothing.

The command has no flags of its own. It takes the global flags (Global Flags).

Without root, some facts cannot be read: the device and its project, as the agent’s .flock is root’s alone, and on an appliance, whose folder /opt/ironflock is root’s, also the versions, the appliance’s URL, its license and its update, and the agent’s update. The health of the appliance’s services needs root or the group docker. They say unknown (needs root), the JSON field needs_root lists them, and sudo ironflock status reads them.

# What is on this machine, read as your login ironflock status # Everything, as JSON sudo ironflock status --json # The status of another machine over SSH ironflock --host pi@device-17 status

Text Output

$ ironflock status Agent: installed in /opt/ironflock/device-agent Version: 1.6.9 Service: running (ironflock-device-agent.service) Connection: unknown (this agent does not report it) Device: unknown (needs root) Swarm: unknown (needs root) Update: none pending Appliance: not installed System: Debian GNU/Linux 12 (bookworm) Run 'sudo ironflock status' to read what needs root.

Swarm is the device’s project. Connection is unknown for a running agent: the agents released so far do not report their connection on the machine.

On IronFlockOS

The system line shows the image and its two root slots (Root Slots and the Data Partition):

System: IronFlockOS 0.13.0 (amd64-efi, base) Image: ironflockos-amd64-efi-base (build 20261105T120000Z-g1a2b3c4) Slot A: inactive, good Slot B: booted, good, 0.13.0 installed 2026-11-05T14:00:00Z Next boot: slot B

The agent of an IronFlockOS device is the one the image set up when the device enrolled, in /opt/ironflock/device-agent on /data, and is shown as on any other system. A device that has not enrolled yet has no agent; the image carries one, and the line says how the device enrolls (first line below). When /data could not be mounted at this start, the agent’s folder cannot be seen either, enrolled or not, and the line says so instead (second line):

Agent: not enrolled yet: the device enrolls with a .flock on its IRONFLOCKOS partition at its next start, or now with 'sudo ironflock agent configure -c <file>' Agent: not to be seen: /data, which holds the agent and its .flock, could not be mounted (below); a .flock on the IRONFLOCKOS partition enrolls the device at its next start for as long as /data is missing

Below the system, one line each appears only when IronFlockOS has something to say:

LineShown when
Last reset:the last factory reset failed or gave up. os reset says what a record means
Reset hold:a reset is open (wait: a .flock or proxy.conf on the IRONFLOCKOS partition is not taken while the old owner’s data may be on /data; copy: the reset has begun to erase), or it gave up and could not remove the .flock and proxy.conf that came with it, which stay unused (gave-up)
/data:/data could not be mounted: the device runs on the root slot’s own folders, without Docker and the apps
/apps:/apps is not the data partition’s folder: the apps run, but lose their data at the next OS update
Last reset: gave up after 3 attempts at 2026-11-11T09:00:00Z: the data partition is not the partition named data on the disk of the root slot; /data holds the old data; left of the old owner: the data partition, the booted root slot, the other root slot Reset hold: wait: a reset is open; a .flock or proxy.conf on the IRONFLOCKOS partition is not taken while the old owner's data may be on /data /data: NOT MOUNTED: the device runs on the root slot's own folders; Docker and the apps do not run, and what is written now is lost with the next update /apps: not the data partition's folder: the apps run, but lose their data at the next OS update

A failed attempt of a reset reads attempt 1 of 3 failed at <time>: <reason>; /data holds the old data; the next start tries again while the hold is wait or copy, and no request is open now without a hold. Without root, the reset record shown is its copy in the running slot, as the IRONFLOCKOS partition is root’s.

The Last os install

On any Linux with EFI variables, a line OS install: shows what the last ironflock os install recorded in IronFlock’s EFI variable IronFlockInstall, when it is there. Every user may read the variable. Where it cannot be read, or the machine has no EFI variables, there is no line and no warning; a value that does not parse is a warning.

System: Debian GNU/Linux 13 (trixie) OS install: 'ironflock os install' stopped at 2026-11-11T10:00:00Z before it wrote the disk: the disk /dev/sda is not the plan's: its size changed from 64.0 GB to 32.0 GB; nothing was changed, and this system runs as before
StageThe line says
stoppedit stopped before it wrote the disk, the reason, and that nothing was changed
handed-overon the old system: the installer did not run at the restart, and nothing was changed. On IronFlockOS: it wrote this system but could not record how the install ended
writingit began to write the disk and did not record that it finished
doneon IronFlockOS: this system was installed by os install. Elsewhere: it wrote IronFlockOS onto a disk of the machine, and the running system is another one
failedit wrote the disk, and what it wrote did not read back, with the reason

The record is never cleared. The line stays until the next os install replaces it, and on a converted device it stays as the note that the system was installed this way.

JSON Result

--json writes the same as one JSON object, shown here on several lines; the command writes it on one line.

{ "agent": { "installed": true, "layout": "current", "dir": "/opt/ironflock/device-agent", "version": "1.6.9", "service": {"unit": "ironflock-device-agent.service", "state": "running"}, "connection": "unknown", "device": "demo-device", "swarm": "demo_swarm", "update": {"state": "none"} }, "appliance": {"installed": false}, "os": {"name": "Debian GNU/Linux 12 (bookworm)", "id": "debian", "version": "12", "ironflockos": false}, "needs_root": [] }

A fact that cannot be read is unknown; when root is not the reason, a warning on stderr says why.

FieldValues
agent.installedtrue when an agent is installed. The fields from layout to update are there then, and only then. On IronFlockOS, false means that the device has not enrolled yet
agent.unfinished_installtrue: no agent, but an earlier install stopped before it got to the agent; agent install undoes it first. Absent otherwise
agent.layoutcurrent (/opt/ironflock/device-agent), legacy (/opt/reagent, from an earlier installer), migrating (the agent moves the legacy layout to the current one right now)
agent.dirthe agent’s folder
agent.versionwhat the agent’s binary says with -version
agent.serviceunit and state: running, starting, stopping, stopped, failed, not_found (systemd does not know the unit), unknown
agent.connectiondisconnected when the agent does not run. A running agent’s connection is unknown; connected comes from agents that report it
agent.device, agent.swarmthe device’s name and its project, from the .flock. Nothing else of the .flock is read
agent.updatethe last self-update. state: none (nothing in progress, nothing failed), activating, probation (the new version runs and has to connect to prove itself), rolled_back (it failed, the previous version runs again, the new one is tried again later), blocked (it failed for good; the agent waits for a newer release), unknown. With version, previous_version, reason and updated_at
appliance.installedtrue when the IronFlock appliance is installed (its unit ironflock.service is there); then dir, version, channel, url, license, service, health and update are there
appliance.data_leftonly when the appliance is not installed and /opt/ironflock still holds its data, left by appliance remove without --purge or by an install that stopped: that folder
appliance.version, appliance.channelthe files VERSION and CHANNEL in its folder
appliance.urlthe address of its UI: HOME_URL of its .env. Nothing else of .env, which holds its secrets, is read
appliance.licensepresent when its license.env holds a license key, missing when not, invalid when its LICENSE_KEY is not a license key (a UUID): every command of the appliance ignores such a key, and the text says so. The key is never shown
appliance.serviceironflock.service, with the states of the agent’s. running means that the unit started the containers, not that each of them is healthy
appliance.healthhow its services are, from docker ps: state healthy (each runs and passes its health check, or has none, or ran once and ended with 0), starting (a health check is pending), unhealthy, down (no container), unknown; services, how many containers; problems, each service that is not healthy with its state (unhealthy, starting, restarting, exited with exit_code, …)
appliance.updatean update that waits, from the status file that its UI and its retry timer write: state none (none asked for, or the last one is done), running, failed (the retry timer tries it again), unknown; with version, since and message. cut_short (root only) names the release whose files an update that was cut short kept: the next update puts them back first. No release is looked up
appliance.ironflockonly when the ironflock that the appliance’s units run at every start (path, /usr/local/bin/ironflock) is missing or older (state; version, what it says) than the one that last installed or updated the appliance (installed). Root only, and only for an appliance that ironflock installed. The text has an ironflock: line then, which says what to install
os.name, os.id, os.versionPRETTY_NAME, ID and VERSION_ID of /etc/os-release; on a Mac macOS 15.5, macos, 15.5
os.ironflockostrue on IronFlockOS. Then os.version is its IMAGE_VERSION, and the fields below follow
os.image, os.buildIMAGE_ID and BUILD_ID of the image
os.booted_slot, os.primary_slotthe slot the system runs from, and the one the next boot starts: A or B
os.slotsthe root slots: name (A), rauc_slot (rootfs.0), state (booted, active, inactive), boot_status (good, bad), and version and installed_at of the release an update installed there (absent for a slot written with the image). Absent when the slots cannot be read
os.last_resetthe last factory reset’s record, only when it is failed or gave-up: result, time, version, attempt, attempts_max, reason, data (old, new, none: what /data holds now), and for gave-up left (of data, booted-slot, other-slot: what of the old owner may still be there)
os.reset_holdwait, copy or gave-up, only while a reset hold is there (see the table above)
os.data_missingtrue, only when /data could not be mounted
os.installwhat the last os install recorded, on any Linux with EFI variables, only when it is there and can be read: stage, time (RFC 3339, UTC) and reason (with stopped and failed)
os.apps_not_persistenttrue, only when /apps is not the data partition’s folder
needs_rootthe fields that say unknown because the command did not run as root, such as agent.device and agent.swarm. Empty when nothing was left out

Exit Code

The exit code is 0 whenever the overview is written, also when it shows a stopped agent, a rolled-back update or a bad slot: status reports and does not judge, and a script reads the fields. It is 1 when the overview cannot be written. For the other exit codes, see Exit Codes.

ironflock doctor

Checks whether this machine can run the device agent, and whether it reaches the hosts the agent talks to: the system, systemd, Docker, the free disk space, the clock, DNS, the proxy, the download server, and the hosts the device’s .flock names.

ironflock doctor [flags]

Runs on: Linux and macOS. Root: not required; a check that cannot look without root is skipped and says so. Asks: nothing.

FlagMeaning
-c, --config <file>the device’s .flock file, whose hosts are checked (default: the installed agent’s)

agent install runs these checks, all but privileges and docker, before it changes anything, and stops when system, systemd, disk_space or download_tree fails.

# Check this machine, as your login ironflock doctor # Check everything as root, as JSON sudo ironflock doctor --json # Check the hosts of a .flock before you install it ironflock doctor -c device.flock

Results

Each check has an id, a result and a finding of one line. A result other than ok comes with a hint that says what to do.

ResultMeans
oknothing to do
warningit may work, but not well
failedthe agent cannot be installed, or does not work, as the machine is
skippedthe check could not look; the finding says why

Checks

The checks, in the order they are shown. A check keeps its id; a new check gets a new one.

IdLooks atWhen it is not ok
privilegeswhether the command runs as rootwarning without root when a check could not look; the finding names those checks. Run sudo ironflock doctor
systemLinux, Debian or Ubuntu based (the install takes its packages from apt) or IronFlockOS, and the architecture the agent is downloaded forfailed on another system, warning on another Linux with apt. agent install stops on failed
systemdsystemd runs the system (/run/systemd/system is there)failed when systemd does not run the system; agent install stops then. warning while the system is degraded: a unit failed
dockerDocker runs (docker info)ok without Docker, as agent install brings it, but failed under an installed agent. skipped without root when the user is not in the group docker
disk_spacethe free space for /opt/ironflock and for /var (Docker, apt, the logs)failed below 128 MiB in /opt: an install or an update of the agent keeps its binary there twice. warning below 2 GiB in either
clockthis machine’s clock against the Date of the download server’s answer, and its Age when a cache kept itok within 10 s, warning up to 5 minutes, failed beyond: signed requests and short-lived tokens are refused, and the apps’ data carry the wrong time. A clock far off breaks TLS itself: failed, with the time the machine has. See Time Synchronization (NTP)
dnsthe names this machine resolves itself: the hosts it reaches directly, and the proxya name does not resolve. A host reached through the proxy is the proxy’s to resolve
proxythe proxy the network checks go through, and where the setting comes from: the install’s record (/etc/ironflock/proxy.env), else the environmentfailed when it is not the URL of a proxy. skipped without root when the record is in the file, which only root reads
download_treethe agent at the download server that agent install takes: its channel map, as agent install reads it (device-agent/manifest-v2.json, else manifest.json), and the agent of the production channel for this architecture. With an appliance’s mirror, what the mirror does not give is looked for in the IronFlock cloud, as agent install takes it: the whole agent when the mirror gives no channel map, the agent’s file when it gives the map without the filefailed when there is no agent to download, with the appliance’s mirror when neither the mirror nor the cloud has it; agent install stops then. A server error (5xx) is a warning, and so is an agent that the cloud gives where the mirror does not
device_endpointthe .flock’s device_endpoint_url answersno answer: the agent connects to IronFlock there
docker_registrythe .flock’s docker_registry_url answers (https://<host>/v2/; with a port, plain HTTP, as an appliance’s registry on the LAN)no answer: the device pulls its apps’ images from there
update_serverthe agent’s update server has its channel map: the .flock’s update_url (an appliance’s mirror), else the IronFlock cloudno answer or no channel map: the agent finds its updates there

The download server is the one agent install takes: --download-base, else the environment variable IRONFLOCK_DL_BASE, else the download mirror of the appliance that the .flock names (its update_url, when that is not a host of the IronFlock cloud), with the cloud for what the mirror does not give, else the IronFlock cloud (Where the Agent Comes From). The hosts a device must reach are listed in Network Requirements.

With and Without -c and Root

The last three checks need a .flock: the one of -c, else the installed agent’s.

As rootWithout root
Without -cthe hosts of the installed agent’s .flockthe last three checks are skipped: the installed agent’s .flock is root’s alone
With -cthe hosts of the .flock giventhe hosts of the .flock given

Without root, also docker is skipped outside the group docker, and proxy is skipped when the install recorded the proxy. A network check whose host gives no answer is then skipped too (for dns, a name that does not resolve), as it may get one through the recorded proxy. privileges names every check that could not look, and sudo ironflock doctor runs them.

How the Network Checks Decide

  • A host answers when an HTTP answer comes, whatever its status. A 502, 503 or 504 to a plain HTTP request through the proxy is no answer: the proxy gives it when it cannot reach the host.
  • A certificate that TLS refuses is no answer. The one exception is the certificate of an appliance’s own CA, when the .flock names an appliance_domain: the agent trusts it.
  • The checks go through the proxy of the check proxy, by the rules of HTTPS_PROXY, HTTP_PROXY and NO_PROXY that the downloads follow, also for every request of a redirect, and wait 20 s for an answer.
  • A host that an entry of NO_PROXY keeps off the proxy goes direct. When it gives no answer that way, the finding names the entry, for example (directly: instance-registry.ironflock.com is in NO_PROXY), and the hint says to take the entry out, with the agent configure --no-proxy that does it when the setting is the install’s record.

Output

$ sudo ironflock doctor Download base: https://instance-registry.ironflock.com/dl Device file: /opt/ironflock/device-agent/device-config.flock CHECK RESULT FINDING privileges ok runs as root system ok Debian GNU/Linux 12 (bookworm), amd64 systemd ok systemd runs this system docker ok Docker 27.3.1 runs disk_space ok 50.0 GB free for /opt and /var clock ok within 10 s of the download server's clock dns ok resolves instance-registry.ironflock.com, cbw.ironflock.com, europe-docker.pkg.dev proxy ok none: the connections go direct download_tree ok https://instance-registry.ironflock.com/dl has the agent 1.6.9 for amd64 device_endpoint ok cbw.ironflock.com answers docker_registry failed europe-docker.pkg.dev cannot be reached: no answer within 20 s update_server ok https://instance-registry.ironflock.com/dl has the agent's updates What to do: docker_registry: the device pulls its apps' images from there: let this machine reach europe-docker.pkg.dev on port 443, directly or through the proxy Failed: docker_registry.

With the appliance’s mirror of the .flock, the first line says so:

Download base: http://10.0.0.5:15002/dl (the appliance's mirror of the .flock; the IronFlock cloud for what it does not give)

With --json, shortened here and shown on several lines; the command writes one line.

{ "result": "failed", "checks": [ {"id": "privileges", "result": "ok", "finding": "runs as root"}, {"id": "docker_registry", "result": "failed", "finding": "europe-docker.pkg.dev cannot be reached: no answer within 20 s", "hint": "the device pulls its apps' images from there: let this machine reach europe-docker.pkg.dev on port 443, directly or through the proxy"} ], "download_base": "https://instance-registry.ironflock.com/dl", "flock": "/opt/ironflock/device-agent/device-config.flock" }
FieldValues
resultfailed when a check failed, warning when one warned, else ok. A skipped check fails nothing
checksthe checks, in the order above: id, result, finding, and hint with every result but ok
download_basethe download server checked. With the appliance’s mirror, the mirror alone; the findings name the cloud when they look there
flockthe .flock whose hosts were checked; null without one

No output shows a secret: of a .flock the checks read the hosts alone, and a proxy’s password shows as xxxxx.

Exit Code

The exit code is 0 when no check failed; a warning does not fail. It is 1 when a check failed: the result says which, and no error line follows it, and with --json stdout has the result, not an error object. It is 1 with an error when the .flock of -c cannot be read. For the other exit codes, see Exit Codes.

Last updated on