Skip to main content

An endpoint stopped reporting

What Stale means, the 15-minute threshold behind it, whether anything actually notifies you, and the ordinary causes to rule out before the sinister one.

Written for whoever runs IT9 min readUpdated

Enrolled, but no telemetry yet

Enrolled confirms that the device registered. A last-seen value of Never means the console has not recorded a successful telemetry receipt. Check that the sensor service is running, the device can reach the configured Qorionix address, and the logs do not show authentication failures or repeated upload timeouts. Preserve any queued telemetry while investigating; reinstalling or deleting the queue can remove useful evidence. Confirm recovery with a recent last-seen time and new received events, not just a running service.

An endpoint that was reporting is now marked Stale in the console, with the subtitle Silent for over 15 minutes. This article explains exactly what that label is measuring, then works through the causes in the order they are actually worth checking. Most of the time the answer is boring, and the boring answers are at the top for a reason: a laptop in a bag is a far more common explanation than an attacker who disabled your agent, and checking in the wrong order costs you an hour.

What Stale actually measures

There is no separate heartbeat call from the sensor to the platform. Liveness is a side-effect of telemetry: every time a batch of events is accepted, the endpoint's last-seen timestamp is stamped to now and its stored status is set to online. So checked in and sent something are the same event.

The effective interval is therefore the upload flush interval, which is 5 seconds, or sooner if 64 events accumulate. A machine with genuinely nothing to report still sends a heartbeat event roughly every 30 seconds on Linux and macOS when the richer sources are unavailable, and that touches the row too. Against an expected gap of seconds, the staleness threshold is 15 minutes — comfortably longer than any normal check-in gap, and short enough that somebody watching a rollout notices a host that never came back.

Staleness is computed at the moment you read the list. It is not stored, and nothing sweeps the table:

How the status you are shown is derived
CASE
    WHEN last_seen_at IS NULL THEN status
    WHEN last_seen_at < NOW() - INTERVAL '15 minutes' THEN 'stale'
    ELSE status
END

This matters for one specific reason. Every endpoint carries two status fields: the stored one, and the effective one the console shows you. A laptop unplugged three weeks ago still has online stored against it, because the stored value is only ever written forward by an accepted batch. The fix for that was to derive the truth on read rather than to mutate rows during a GET. The reasoning is worth quoting, because it explains a design you might otherwise read as sloppiness: a row that only gets corrected when somebody happens to look at it means the truth of your fleet depends on who opened which page.

The four statuses an endpoint can display, and the tile wording that goes with each in the console.
StatusShown asMeaning
onlineReporting — Checked in recentlyA batch was accepted within the last 15 minutes.
staleStale — Silent for over 15 minutesEnrolled, has reported before, and has not reported recently.
enrolledAwaiting first check-in — Enrolled, never sent telemetryThe endpoint record exists because a token was spent. No telemetry has ever arrived. Last seen shows Never.
revokedRevokedThe endpoint's own credential has been withdrawn. Its requests are refused at the door.

The causes, in the order worth checking

Causes of a stale endpoint from most to least likely, with the check for each. Work down the list rather than jumping to the bottom.
CauseHow to check itWhat it looks like
The machine is off, asleep or off the networkAsk the person who uses it. Compare the last-seen time with when they went home.Nothing in the local log because nothing is running. Last seen lands neatly at the end of a working day.
Outbound HTTPS is blocked or the network changedOn the machine, look for sensor: cannot reach <endpoint> (<err>) — <n> events dropped in the log.The service is running and complaining. A new firewall rule, a captive portal, a VPN split-tunnel change, or a proxy that intercepts TLS.
The service is stopped or crash-loopingsc query ZentryQSensor on Windows; sudo systemctl status zentryq-sensor on Linux; sudo launchctl print system/eu.zentryq.sensor | head -20 on macOS.No recent log lines at all. On Linux the unit restarts always with a 5-second delay and a budget of 10 starts in 300 seconds, so a hard crash loop eventually stops trying.
The sensor is being upgraded — by a person, or by itselfCompare the endpoint's reported version before and after the gap. If it changed, check whether anybody ran a package-manager or MSI job on that host around the last-seen time.A short, self-resolving gap ending with a new version number. This is not on its own evidence that somebody ran an installer — the sensor carries its own updater. See the note below before you go looking for a culprit.
The endpoint's own credential is being refusedLook for a 401 or 403 line in the local log — the exact wording is in the next section.The service is healthy, the network is fine, and every batch is rejected. Usually the endpoint was revoked in the console.
Telemetry is being accepted and the timestamp update is failingRare, and not visible from the machine. Raise it with us.The events arrive and are searchable, but last-seen stops advancing, so the endpoint reads as stale while working.
Somebody stopped the agent on purposeOnly after the six above. Check who has local administrator rights on that machine and when the service last stopped.A service stopped or uninstalled outside a change window, with no upgrade to explain it.

The last row is the one everybody reaches for first, and it is last on purpose. Disabling security software is a real attacker technique and we detect it where we have the telemetry to do so. It is also, on any given Tuesday, a far less likely explanation than a closed laptop. Rule out the cheap causes and you will spend your suspicion where it is worth something.

What the local log says

The sensor is explicit about delivery failures and throttles repeats to one line per distinct message per five minutes, adding a suffix so you know how much was collapsed. These are the lines to search for:

Telemetry delivery messages from the sensor
sensor: telemetry rejected with HTTP <code> — <n> events dropped
sensor: cannot reach <endpoint> (<err>) — <n> events dropped
sensor: could not encode <n> events: <err>
sensor: telemetry delivery recovered
<message> (<n> similar messages suppressed)

For the two credential cases the sensor writes a full sentence rather than a status code, because the remedies are different and neither is obvious from a number:

sensor: the server rejected this endpoint's credential (HTTP 401). Re-run the installer with a fresh enrolment token, or check the endpoint has not been revoked in the console.
Sensor log, on a 401 from the ingest endpoint
sensor: the server refused this endpoint's identity (HTTP 403). This usually means the local config names a sensor that belongs to a different machine.
Sensor log, on a 403 from the ingest endpoint

The 403 case has one dominant cause: a configuration file copied from another machine, or baked into a golden image after enrolment. The identity in the file does not match the machine presenting it, and the platform refuses rather than accepting one machine's telemetry under another machine's name. The server side of the same refusals reads missing sensor auth context at 401 and sensor_id in body does not match authenticated sensor at 403; behind the middleware the four possible auth failures are sensor auth: missing bearer token, sensor auth: unknown enrollment token, sensor auth: sensor revoked and sensor auth: auth lookup failed.

What to do

  1. Read the last-seen time before anything else

    It is the single most informative field. A gap that begins at 17:40 and ends at 08:55 is a person going home. A gap that begins mid-morning and never ends is worth investigating. Never in that column means the endpoint has never reported and this is an enrolment problem, not a reporting one.

  2. Get to the machine, or to somebody who can

    Almost every diagnosis in the table above needs the local service status or the local log. If you cannot reach the machine, you cannot distinguish switched off from agent stopped, and the console cannot do it for you.

  3. Restart the service before you reinstall

    A restart fixes a wedged process and costs nothing. sudo systemctl restart zentryq-sensor, or the equivalent on your platform. Reinstalling is a bigger act than it looks, because re-running enrolment replaces the configuration file in full.

  4. Re-enrol only if the credential is being refused

    If the log shows the 401 sentence above, mint a fresh enrolment token and re-enrol. Re-enrolment updates the existing endpoint record rather than creating a second one, so you will not end up with a duplicate. It also clears an earlier revocation, which is what you want if the machine was revoked by mistake.

  5. Decide what a permanently silent endpoint means to you

    A machine that has been stale for a month is either gone or unmonitored, and both need a decision. Revoke the ones that have genuinely been retired, so that the list you scan is a list of machines you still expect to hear from.

One last message you may meet on the way: The endpoint list could not be loaded. That is the console failing to read the list at all, not a statement about any endpoint. Retry, and if it persists see How to get help.

Was this article wrong?

If a procedure here does not match what you see, or a limit we described has changed, tell us and we will fix the page. Email us about this article, or see how to get help if you need an answer rather than a correction.

Everything in troubleshooting