Reconnecting
Restoring connection…
Reconnecting
Restoring connection…
Docs navigation
Get started
AI agents
Connect
The fleet
Operate
Day to day
When it breaks
Govern access
Team & account
Access
Identity concepts
Provider guides
Account
Upgrade runners
Move a runner fleet to a new release. Start with one canary, verify the result, and keep the previous version ready for rollback.
To upgrade the workstation bridge instead, see Upgrade the MCP bridge.
- Owner or admin in the account — you will read runner versions and run history in the console.
-
Root or sudo on each runner host. The installer writes to
/usr/local/binand the service unit. - One non-critical runner to go first.
- The release you are currently on, written down. You need the exact tag to go back to it.
Who upgrades what#
Four parts upgrade separately — upgrading one never upgrades another.
| Component | Who upgrades it | How |
|---|---|---|
| Control plane | We do | Nothing for you to run. Shipped changes land in the changelog. |
| Runner binary | You, per host |
Run sudo emisar update. It stops and restarts the service.
|
| emisar-mcp bridge | You, per workstation | Re-run the installer — Upgrade the MCP bridge. Cloud OAuth clients run no bridge. |
| Action packs | You, per runner | Updated separately, with their own trust decision — Roll out and roll back packs. |
Find the versions you run#
The console shows the version that each runner last reported — the Runners list carries it per host. On the host, run:
# one machine-readable line: "emisar version X.Y.Z" $ emisar --version # the same version plus Go, platform, and build metadata $ emisar version
Compatibility status#
Each version a runner reports is compared against two published numbers: the oldest release we still support, and the one we recommend you run.
| Value | Current setting |
|---|---|
| Minimum | >= 0.10.0 |
| Recommended release | 0.19.0 |
- — outdated is above the minimum but behind the one we recommend. It keeps working. The console shows a version chip, and nothing else changes.
- — unsupported is below the minimum. The runner is flagged on the Runners page. It still connects today, but that is not a promise. Upgrade it.
The version is self-reported, so treat it as housekeeping, never a security control — what a runner may do is decided by your policies and pack trust, not by the version it claims.
Upgrade your runners and bridges in the same pass. For which versions work together, see compatibility and deprecation.
Plan the rollout#
- Read the changelog for the releases between your current version and the target.
- Write down the version you run today. That tag is your way back. Nothing in the product remembers it for you.
- Check Runs for work in flight on the hosts you are about to touch. Filter to running and sent, and let anything long-lived finish first.
- Pick one non-critical runner as the canary. Ideally in a group whose actions you can exercise safely.
Upgrade one runner#
The runner updates to the latest stable immutable release by default. Pin the release on the canary so every later host gets the exact same release.
# on the canary host $ sudo emisar update --version <target-version>
This command works only for a runner installed by install.sh, which records the paths it owns in a root-owned receipt. A copied
binary, container image, or infrastructure-managed runner is refused — update that
deployment at its source instead of letting the host drift from it.
Verify this download first
The installer checks the checksums for you. emisar also publishes a signed attestation for every release, so you can prove the binary came from our source before it runs as sudo.
Download the release and run both checks — the attestation names our source repository and the release workflow that built it.
# provenance — built by our workflow, from our source $ gh attestation verify emisar-<version>-linux-amd64.tar.gz --owner andrewdryga # checksums — the bytes match what we published $ sha256sum -c SHA256SUMS
More on the signing pipeline: Release integrity.
The update touches only the binary: config.yaml, runner.env, the cached token, installed packs, the dispatch log, and the local
audit journal all stay as they are. Before the service stops, it verifies the release and
archive checksum (an authenticated
gh
CLI also checks the build attestation), stages the binary, checks its version, and
confirms the new binary can read the current dispatch state.
Once the preflight passes, the installer stops the service, swaps the binary, and starts it again. A runner kills its children when it exits, so an action in flight on that host is interrupted — let running work finish first.
If any later step fails, the installer restores the previous binary, runner.env, and cached
token, restarts the service if it was running before, and exits nonzero. Packs installed
during the attempt stay installed.
Verify the canary#
Six checks, in order — stop at the first one that fails.
# 1. the binary is the version you pinned $ emisar --version # 2. the service came back and stayed up $ systemctl status emisar # 3. config, credential, packs, action binaries, and reachability $ sudo emisar doctor # 4. the packs and hashes this host will advertise $ sudo emisar pack list
Then verify the console. In Runners, confirm that the canary is online with the new version and expected actions.
Run one low-risk read-only action. Confirm that it succeeds and appears in Audit. The audit row is what completes the check —
doctor
covers the host, and only a real run shows the whole path works.
Roll through the fleet#
Repeat the same two steps — upgrade, then the full verification — in bounded batches, one runner group at a time. Halt when any of these happens:
- — The update exits non-zero. If the swap had started, that host is already back on its previous binary — read the output before you touch the next host.
-
—
emisar doctorreports a failed check, or the runner does not come back online within its usual reconnect window. - — The advertised action set changed in a way the release notes did not describe, or a pack lands as pending trust in Packs.
Go to production owns fleet shape and batch sizing. Manage the runner fleet owns groups, labels, and host-side removal.
Return to a known-good release#
Going back is the same update command with the version you wrote down, followed by the same verification.
# runner — the release you were on before $ sudo emisar update --version <known-good-version>
Rollback has two limits. Only a finished, published release installs — a draft or one still being written is refused. And the older binary must be able to read the current dispatch state; if it cannot, the installer refuses and the current installation keeps running. Rollback works only within the supported release line — go back no further than the minimum above.
An upgrade or rollback never touches packs. If the problem is an action's behavior rather than the runner, the version to change is the pack's. See Roll out and roll back packs.