Endpoint agent and browser extension problems
Agents that will not enrol or stop checking in, extensions that cannot attest, and an EDL feed the firewall stops receiving.
- Version: 0.4
- Role: admin_user
- Type: troubleshooting
Both surfaces authenticate a machine rather than a person, so their failures are about identity material — an enrolment token, a device-bound key, a signed policy bundle — and not about passwords.
Find your symptom
| What you see | Runbook |
|---|---|
| An agent will not enrol | An agent will not enrol |
| An agent enrolled once and never checked in again | An agent will not enrol |
| A policy change never reached the fleet | A policy change does not reach the fleet |
| The extension says attestation was rejected, or the device is not enrolled | The extension cannot attest |
| The extension signs in and says this role has no extension view | The extension cannot attest |
| The firewall stopped receiving the EDL feed | The EDL feed stops updating |
| The extension cannot reach the appliance at all | Certificate and 443 problems |
The endpoint agent
An agent will not enrol
Enrolment matches the token's hash to a fleet and requires that fleet to be active, so deactivating a fleet stops new enrolments without revoking the devices already in it — and both read as an invalid token.
After enrolment the agent authenticates with an ordinary gateway API key, so the key's own lifecycle applies: revoke it or let it expire and the agent goes quiet with no endpoint-side change at all.
Note
A key is bound to one device id. Cloning a machine image after enrolment gives two machines the same key with different device ids, and both are refused. Exclude the agent's state from the golden image.
An endpoint agent will not enrol, or stops receiving policy
You might see: Invalid enrollment token · Missing agent API key · Invalid agent API key · Agent key does not match device
Before you start
Checks
- 1
Check the enrollment token against the fleet
expected · The token belongs to a fleet whose status is active.
- 2
Read the Authorization header the agent sends on policy and heartbeat calls
expected · The agent sends a key the gateway recognises.
- 3
Check that the key and the device id agree
expected · The key resolves to the device id the agent claims.
- 4
Read the fleet's policy for the two fields the bundle cannot be signed without
expected · Both are present.
- 5
For a policy change the fleet never adopted, check that the bundle version advanced
expected · The version is higher than the one the agent reports.
Causes and fixes
| Reached when | Cause | Explanation, fix and verification |
|---|---|---|
| check 1 fails | token-or-fleet-inactive (warning) | Enrolment matches the token's hash to a fleet and requires that fleet to be active. Deactivating a fleet therefore stops new enrolments without revoking the devices already in it, and both failures read as an invalid token. Fix: Re-activate the fleet, or issue the agent the token of a fleet that is active. Verify: expected · The device appears in the fleet. |
| check 2 fails | agent-key-missing-or-invalid (critical) | After enrolment the agent authenticates with a gateway API key like any other API client, so the key's own lifecycle applies: revoke it or let it expire and the agent goes quiet without any endpoint-side change. Fix: Check the key under Access Keys and follow A gateway API key is refused. Re-enrol the device if the key cannot be restored. Verify: expected · It is recent. |
| check 3 fails | key-device-mismatch (warning) | A key is bound to one device id. Cloning a machine image after enrolment is the usual cause: two machines then present the same key with different device ids, and both are refused. Fix: Re-enrol the affected machines so each gets its own key, and exclude the agent's state from the golden image. Verify: expected · Each machine appears once, with a recent heartbeat. |
| check 4 fails | policy-incomplete (warning) | The signed bundle must state how selective the agent is and what it does when it cannot reach the appliance. A bundle missing either is refused at signing rather than shipped with a default the operator never chose. Fix: Set selectivity and failMode on the fleet policy and save it again.Verify: expected · A signed bundle is returned. |
| check 5 fails | version-did-not-move (info) | Agents adopt strictly-increasing bundle versions, so a change that does not advance the number is a change the fleet never hears about. Lock and unlock transitions move the number through a generation offset for exactly this reason. Fix: Save the policy again so its version advances, then wait one poll interval. Verify: expected · It matches the fleet's current version. If that does not apply: Attach the support bundle, the fleet id, the device id and the agent's own log. |
A policy change does not reach the fleet
An agent adopts a bundle only when its version is strictly higher than the one it applied. A change that does not advance the number is a change the fleet never hears about — which is why lock and unlock transitions move it through a generation offset.
The bundle is also refused at signing when the policy is missing selectivity or failMode,
rather than shipped with a default nobody chose. The same runbook covers both.
The browser extension
The extension cannot attest
Four refusals are deliberately distinct: a device that was never enrolled, a device enrolled to another tenant, key material of the wrong shape, and a device being refused for frequency because it is re-attesting in a loop. A role with no extension view is told so at sign-in rather than shown an empty popup — that is the same design as the chat refusal for audit roles.
The browser extension cannot attest, sign in, or fetch its policy
You might see: Attestation rejected · Device is not enrolled · Device is enrolled to another tenant · Device not found
Before you start
Checks
- 1
Read the device's enrolment
expected · The device is enrolled to the tenant the user belongs to.
- 2
For a rejected enrolment, read what key material the extension sent
expected · The extension sends a P-256 public JWK.
- 3
Check whether the device is being refused for frequency rather than identity
expected · The device attests at its normal interval.
- 4
Read the role of the account signing in
expected · The role is one that uses the extension.
- 5
For the firewall EDL feed, read the token the firewall presents
expected · The firewall presents a current EDL token.
Causes and fixes
| Reached when | Cause | Explanation, fix and verification |
|---|---|---|
| check 1 fails | device-enrolment-wrong (warning) | A device belongs to exactly one tenant. Re-imaging a machine, or moving a user between tenants without re-enrolling, leaves the device attesting against a tenant that no longer matches the signed-in user. Fix: Remove the stale device record and enrol the machine again as the current user. See Browser extension. Verify: expected · The device reports enrolled and healthy. |
| check 2 fails | bad-key-material (info) | Attestation is a signature check. A key of the wrong curve, or one that carries a private scalar, cannot be used for it and is refused rather than stored. Fix: Reinstall or reset the extension so it generates a fresh key pair, then enrol again. Do not copy key material between machines. Verify: expected · Enrolment succeeds. |
| check 3 fails | attestation-throttled (info) | The attestation endpoint is rate limited per device. A device that crashes and re-attests in a loop is refused for frequency, which masks whatever is actually crashing it. Fix: Stop the loop first — read the extension's own error — then let the throttle window pass. See A request is refused for being too frequent. Verify: expected · The attestation is accepted. |
| check 4 fails | role-has-no-extension-view (info) | The refusal is deliberate and is not a fault: the account authenticated successfully and its role has no extension surface. It is the same design as the chat refusal for audit roles. Fix: Use the dashboard with that account, or give the user an account whose role uses the extension. Verify: expected · The extension opens. |
| check 5 fails | edl-token-missing-or-expired (warning) | The EDL feed is consumed by a firewall that cannot sign in interactively, so it carries its own token. An expired token stops the feed updating; the firewall keeps enforcing the last list it fetched, which makes the failure quiet. Fix: Issue a new EDL token in the dashboard and update the firewall's feed URL. Check the feed after the change rather than assuming it recovered. Verify: expected · The feed returns the current list. If that does not apply: Attach the support bundle, the device id and the extension's own log. |
The EDL feed stops updating
The firewall cannot sign in interactively, so the feed carries its own token. An expired token stops the feed updating while the firewall keeps enforcing the last list it fetched — which makes the failure quiet. Check the feed at the firewall after rotating the token; do not assume it recovered.
What the docs cannot tell you
- Why an endpoint agent stopped running at all. The gateway sees only the absence of a heartbeat. Read the agent's own log on the machine.
- Whether a browser policy is blocking the extension. Managed-browser policy is outside CID's view; the appliance sees no request.
Related
- Endpoint agent — fleets, policies and device state.
- Deploying the endpoint agent.
- Browser extension — devices, scopes and the EDL feed.
- Deploying the browser extension.
Last updated on