Skip to main content

Connector lifecycle and updates

An enrolled connector does three things without anybody asking: it heartbeats, it renews its own certificate, and it takes the version Fleet names for it. This page is what each looks like and what you control. Install the connector is how a host gets here.

The heartbeat, and what a dropped session means​

The connector sends a heartbeat every 30 seconds (heartbeat_seconds in /etc/fleet-connector/connector.yaml), and the gateway acknowledges each one it accepted. Those acks are the liveness check in both directions: the gateway drops a session silent for 75 seconds, and the connector's watchdog ends one after three unanswered heartbeat intervals, 90 seconds at the default, then redials with a backoff from 1 second to a ceiling of 60.

A host reads Connected while a heartbeat has arrived in the last 90 seconds. With no live session it reads Disconnected, and the services on it stop reporting until the connector dials back in.

How a host learns that a new version exists​

Fleet names one current release, and the gateway puts a directive on a heartbeat ack: the version, the artifact URL and the SHA-256 the bytes must hash to. The checksum arrives over the mTLS session, never from the download site, because a checksum served beside its own binary proves nothing.

The connector decides for itself, on the host, and logs every refusal:

  • an artifact URL that is not https, not on dl.fleet.wazuh.com (or a host the config named), or not this platform's exact per-version key, core/<version>/fleet-connector_<os>_<arch>, re-checked on every redirect hop. A plugin is bound the same way to its own service's download site, which the connector carries compiled into the binary rather than reading it off the wire. Fleet chooses which version a host takes, never where the bytes come from;
  • the version it already runs, refused as already at X;
  • a version inside its failure backoff: 15 minutes after the first failure, doubling to a ceiling of 6 hours. A fresh press of Update now goes through that window once;
  • for an automatic update, anything that is not a strictly newer vX.Y.Z release. A development build is left out rather than guessed at.

Self-update is armed only for a systemd-started process whose owner has not switched it off; a foreground run logs directives and ignores them.

The install: staged, then privileged, then judged​

The process that talks to the internet never replaces a root binary, and the step that judges a swap is never the binary under test.

  1. The connector service downloads. It streams the artifact into /var/lib/fleet-connector/upgrade/staging/, hashing as it goes, then writes a request. A mismatch stages nothing and says so; the usual cause is the download edge still serving the previous release, and it clears on its own.
  2. fleet-connector reconcile installs, as root with no network, fired by a path unit when the request appears (a timer three minutes after boot and every 15 minutes after that is the safety net). It re-hashes the staged file, installs it under /usr/local/lib/fleet-connector/core/<version>/, requires the candidate's own --version to match, keeps the running binary as /usr/local/bin/fleet-connector.prev, installs over the unit's path atomically, arms the confirm timer and restarts the service. A swap whose timer cannot be armed is undone.
  3. fleet-connector-confirm.sh judges it 180 seconds later. The new process marks itself healthy once it has a session to the gateway, or after 120 seconds without a crash. Matching versions confirm the swap; anything else restores .prev, records the failure and restarts the unit.

The outcome rides every heartbeat until one is delivered, so a failed swap is not lost to the reconnect that follows it, and a staged request nothing acted on for 30 minutes is reported as the reconciler not running here. A failure is also a brake: that version is not offered to that host again automatically until a newer release ships or somebody presses Update now.

A self-update replaces the binary and runs nothing else from the installer, so it does not look for the Wazuh login the host keeps. A host whose installer never looked, because it has only updated itself since it was installed, gets that login for its services once the installer runs on it again, without --token. See The Wazuh login the installer finds.

A release reaches only the canary ring until it is promoted​

  • A release is published at 0 % rollout. It reaches only hosts in the canary ring until Wazuh promotes it, so cutting a Fleet release changes no general-ring host on its own.
  • The wave is deterministic per host, derived from the connector's id and the version, so a host inside it at 10 % is still inside at 50 %. The canary ring ignores the percentage.
  • A halt reaches everybody at once, Update now included: it is refused with the halt's reason rather than setting a pin that can never be satisfied.

A published version names one set of bytes for ever, and no publish can clear a halt, lower a rollout percentage, or make an older version current.

What you control, per host​

The Updates card on a host's detail page.

ControlWhat it does
Follow new releases automaticallyOn by default. Off means hosts stay where they are until somebody presses Update now.
Ringgeneral or canary. Canary takes every release first and ignores the rollout percentage.
Update nowPins the host to the current release. It takes it on its next heartbeat, and the pin retires itself once the host reports that version.
Cancel Update nowClears an outstanding pin, with a note saying who cancelled it.

Changing any of them is an admin act, because it decides when root code on your hosts changes; see Team and roles. A control that cannot succeed says why rather than being greyed out, for example Release 0.4.0 is halted or No connector has enrolled for this host yet.

A pin also retires itself with a note when it can no longer be satisfied: a host has already moved past the version it names, or that version is no longer the current release. The card keeps showing that note until the next update lands.

That pin is the only one there is. Nothing here or in the config holds a host on a version of your choosing: the choice is between following releases and not following them.

What the host owner controls​

The host owner's veto lives in the config file and outranks the console. Edit it, then systemctl restart fleet-connector:

upgrade:
enabled: true # false: every directive from Fleet is logged and ignored
plugins_enabled: true # false: the core still updates, plugin installs do not
download_host: dl.fleet.wazuh.com # the one host artifacts may come from
download_hosts_allow: [] # extra hosts, added to the one above

download_host replaces the default rather than adding to it, so a host pointed at a mirror takes its core only from that mirror. download_hosts_allow is additive, and it is how a mirror or an unlisted plugin site is allowed alongside.

Both toggles default to on. With enabled: false an admin can press Update now all day and the host will not move, and the journal says so at start up: self-update: DISABLED ... every directive from the console will be ignored. See Connector configuration and Services on a host.

Which version a host is on​

The Hosts table has a connector version column, and the Updates card on a host's page says where it stands: on the current release, update to X pending, update to X failed with the host's own reason, behind X when it has not taken the release yet, or not reported, which is never rendered as up to date. On the host itself:

fleet-connector --version
sudo fleet-connector status
journalctl -u fleet-connector -f

status prints the ledger: what runs, what is kept for a rollback, which versions are installed, what is staged or pending, and the last outcome. See Connector logs for the units an update is logged by, and the command reference for every subcommand.

Rolling back by hand​

sudo fleet-connector --rollback # to the previous binary
sudo fleet-connector --rollback --to 0.4.0 # to a version still installed here
sudo fleet-connector --rollback plugin:pharos --to 1.4.0 # a plugin, rather than the connector

A rollback restores the binary, restarts the service, and records the version it undid as failed: undoing an update by hand is the strongest statement that it does not work here. That version is not offered to this host again automatically, while a later release is.

Certificates: renewal, and the one case it cannot repair​

A client certificate is issued for 90 days, and the connector renews it at two thirds of that life, checking 30 seconds after start and hourly after that. It posts a fresh signing request over mTLS with the certificate it still holds, and the gateway re-stamps the subject it was presented with, so a connector cannot renew itself into another identity. The new pair is swapped in and the session ends, so the next dial presents it. A failed renewal changes nothing and is retried an hour later.

The Identity column says Valid, N days left while more than 28 days remain, Renewal overdue, N days left at 28 or fewer, Expires today: renewal is overdue on the last day, and Expired: re-run the installer on the host with a new token after that. A host whose certificate expiry was never recorded reads Not recorded, never as valid.

An expired certificate cannot renew itself

Renewal authenticates with the certificate the host already holds, and the handshake refuses an expired one, so a host powered off across its expiry needs a fresh token and install.sh --re-enroll --token=<TOKEN>. The host's own page mints one: Re-enroll this host. A host that stays powered on renews on day 60 of 90 and never reaches this.

How access ends​

Access ends with the host. Removing one revokes the connector registered for it: the host's routes close when the removal commits, the live session is evicted, and the next dial is refused. The certificate's remaining days are not what ends the access, the check on every dial is, and it fails closed. See Remove a host.

There is no per-connector revoke control, so stopping a single host means uninstalling the connector there, which removes nothing from Fleet.