Skip to main content
CID222 Docs

Update and licensing problems

Bundles that will not upload, releases the updater refuses, host repairs that never reach the host, and licences the appliance cannot verify.

  • Version: 0.4
  • Role: admin_user
  • Type: troubleshooting

Updating and licensing share one root property: both depend on the appliance being able to verify a signature. An appliance with no trust anchor cannot accept a licence and cannot accept a release, and the two failures are usually reported separately by two different people.

For a box that has never been licensed at all, start at Install and activation problems instead.

Find your symptom

What you seeRunbook
The System Updates page shows 0.0.0, or its buttons return 500The updates page is wrong or errors
The appliance cannot say which release it runsThe updates page is wrong or errors
The update check finds nothing, or times outThe channel is unreachable
A bundle upload stalls, resumes wrong, or is refusedA bundle will not upload
An online install is refused for an unpinned hostA bundle will not upload
The updater refuses the release before changing anythingThe updater refuses the release
The update installed and then rolled itself backThe updater refuses the release
A change saved in the dashboard never reached the hostA host repair fails
A licence upload is rejected as a bad signatureA licence will not verify
The appliance can only ever run its trialA licence will not verify
Every product route answers 402The product is locked at 402
One feature is refused with 403 while everything else works402, 403 or 423

The updates page

The updates page is wrong or errors

A missing version stamp, an unset channel, an unreachable channel and a stalled updater all surface on the same page and look alike. Until the version stamp is restored, every comparison against the channel manifest — and every support answer — is meaningless.

Runbookupdates

The System Updates page shows 0.0.0, or the update buttons return 500

You might see: System Updates shows version 0.0.0 · current version 0.0.0 · update check returns 500 · install update → 500

Before you start

Checks

  1. 1

    Read the product version the appliance reports

    diagnostics · appliance.version = "0.0.0"

  2. 2

    Verify an update channel is configured

    diagnostics · appliance.channel

  3. 3

    Verify the release channel answered on the last attempt

    diagnostics · appliance.update.channelReachable = true

  4. 4

    Check whether an update or host-repair intent is stuck waiting for the host updater

    diagnostics · appliance.update.pendingIntent

  5. 5

    Read the host-repair status, which is what the page renders alongside the version

    GET /admin/system-update/host-repair

Runbookupdates

The appliance cannot say which release it is running

You might see: This box cannot say which release it is running · System Updates shows version 0.0.0 · current version 0.1.0 on a box that is not 0.1.0 · the update page offers nothing and shows no version

Before you start

Checks

  1. 1

    Read the product version the appliance reports

    diagnostics · appliance.version = "0.1.0"

  2. 2

    Read the host-repair status, which is what rewrites the version stamp

    GET /admin/system-update/host-repair

The channel is unreachable

Expected on a deliberately air-gapped appliance, which updates from a signed offline bundle. On a connected one it is an egress problem wearing an update-shaped mask.

Runbookupdates

The update channel is not reachable from the appliance

You might see: The update channel host is not reachable from inside the gateway · Check for updates does nothing · update check returns 500 · the appliance never finds a new version

Before you start

Checks

  1. 1

    Verify an update channel is configured at all

    diagnostics · appliance.channel

  2. 2

    Read whether the channel answered on the last attempt

    diagnostics · appliance.update.channelReachable = true

  3. 3

    Read the name-resolution results for the hosts the appliance must reach

    diagnostics · appliance.dns

  4. 4

    Read whether an outbound proxy is configured, on a network that requires one

    diagnostics · appliance.proxy.configured = true

Installing

A bundle will not upload

Uploads are resumable, so the failures are about offsets and expiry rather than about the release. An online install is refused outright unless SYSTEM_UPDATE_ALLOWED_HOSTS pins the host — empty is the shipped default and used to mean "any https host", so the guard was off wherever nobody had configured it.

Runbookupdates

An update bundle will not upload or install from the dashboard

You might see: unknown or expired upload · offset mismatch · incomplete upload: have N of M bytes · bundle filename must end with .cidupd

Before you start

Checks

  1. 1

    Read the bundle's file name

    expected · The file ends in `.cidupd`.

  2. 2

    For a resumed upload, check that the server still holds the partial file

    expected · The status call returns an offset.

  3. 3

    For an offset mismatch, compare what the client thinks it sent with what the server holds

    expected · The client resumes from the offset the server reports.

  4. 4

    For "incomplete upload", compare the assembled size with the declared size

    expected · The two sizes agree.

  5. 5

    For an online install, read the update host allowlist

    expected · The allowlist names the host in the manifest URL, over https.

The updater refuses the release

Every refusal before the smoke test happens with nothing changed: signature and manifest verification, the minimum-version check, the file checksums, the database pre-flight probes, and the check that the current release's images still exist so rollback remains possible.

Note

docker image prune on the appliance host removes the images rollback needs. The updater then refuses to go forward rather than taking a one-way trip — take a hypervisor snapshot before retrying.

Runbookupdates

The updater refuses the release, or stops part-way through installing it

You might see: signature missing · bundle not found · compose file missing from release · cannot jump from X to Y: this release requires at least

Before you start

Checks

  1. 1

    Read whether the failure is the release's signature or the appliance's trust anchor

    diagnostics · appliance.license.trustAnchorPresent = true

  2. 2

    Read the version this appliance runs against the release's minimum

    diagnostics · appliance.version

  3. 3

    Check that the bundle carries everything its manifest references

    expected · No file is reported missing or mismatched.

  4. 4

    Check that the images of the release currently installed are still present

    expected · Every current-release image inspects successfully.

  5. 5

    Read the database pre-flight probes

    expected · Every probe reports clean.

  6. 6

    For an update that installed and then rolled back, read the smoke result

    expected · The smoke test passed.

A host repair fails

Several changes made in the dashboard — a certificate, a TLS mode — are applied by a host-side agent, and the failure mode that costs the most is the quiet one: the write fails, the handler logs and continues, and the dashboard reports success.

Runbookupdates

A host-side repair or reconfigure step fails

You might see: host command failed · host write failed · cannot determine own image · a certificate was applied in the dashboard and the host never changed

Before you start

Checks

  1. 1

    Check whether the agent can identify its own image

    expected · The agent resolves its own image, or `CID_HOST_EXEC_IMAGE` pins one.

  2. 2

    For "host write failed", read which path it was writing

    expected · The path is writable and the filesystem has room.

  3. 3

    Read free disk on the host

    diagnostics · host

  4. 4

    Check the shared state directory, which several features fail through together

    expected · The directory exists and the gateway can write it.

Licensing

A licence will not verify

The licence file is usually fine. An appliance with no signing public key cannot check it, so every licence looks forged — and with enforcement off the same appliance quietly runs its trial, so the gap only surfaces when the trial ends.

Runbooklicensing

License upload fails with 400 "rejected: signature"

You might see: 400 rejected: signature · 400 rejected: ENOENT · License upload → 400 · licence file will not upload

Before you start

Checks

  1. 1

    Verify the licence trust anchor exists on the host

    diagnostics · appliance.license.trustAnchorPresent = true

  2. 2

    Verify the appliance reports an installation id

    diagnostics · appliance.license.installationId

  3. 3

    Verify the host clock is disciplined by NTP

    diagnostics · host.timeSynced = true

  4. 4

    Read the licence state the gateway reports

    GET /admin/license/status → {"state":"active|trial"}

Runbooklicensing

This appliance has no licence trust anchor and can only run the trial

You might see: No license trust anchor (/etc/cid/license-pubkey.pem) · no licence can be verified on this box · the appliance only ever runs the built-in trial · every licence file is rejected, whichever one we upload

Before you start

Checks

  1. 1

    Read whether the licence-signing public key exists on the host

    diagnostics · appliance.license.trustAnchorPresent = true

  2. 2

    Read whether licence enforcement is switched on, which decides how bad the missing anchor is

    diagnostics · appliance.license.requireLicense = false

The product is locked at 402

Enforcement is on and no licence resolves as valid. Administration stays reachable so this can be fixed without a rescue procedure. Check the host clock before requesting a renewal — a drifting clock expires a valid licence.

Runbooklicensing

Every request returns 402 LICENSE_EXPIRED after the wizard completes

You might see: 402 LICENSE_EXPIRED · chat returns 402 after finishing setup · the dashboard loads but every action fails with payment required · product blocked immediately after setup

Before you start

Checks

  1. 1

    Read whether licence enforcement is switched on for this deployment

    diagnostics · appliance.license.requireLicense = true

  2. 2

    Read the licence state the gateway resolved at boot

    diagnostics · appliance.license.state = "active|trial"

  3. 3

    Verify the licence trust anchor exists, since without it no licence can ever resolve as active

    diagnostics · appliance.license.trustAnchorPresent = true

  4. 4

    Check how long the installed licence has left

    diagnostics · appliance.license.expiresAt

Runbooklicensing

The licence has expired and licensed endpoints answer 402

You might see: License expired / product locked · 402 LICENSE_EXPIRED · License state is "expired" · the trial ran out

Before you start

Checks

  1. 1

    Read the licence state the gateway resolved

    diagnostics · appliance.license.state = "active|trial"

  2. 2

    Verify the host clock is disciplined, because a skewed clock ages a valid licence out early

    diagnostics · host.timeSynced = true

  3. 3

    Verify the trust anchor exists, since without it no renewal can ever verify either

    diagnostics · appliance.license.trustAnchorPresent = true

  4. 4

    Read the licence status the API reports

    GET /admin/license/status → {"state":"active|trial"}

  • Updates — the update channel, offline bundles and what an update touches.
  • System updates — the dashboard page.
  • Licensing — issuing, installing and renewing a licence.
  • Error codes — what 402, 403 and 423 mean precisely.

Last updated on

On this page

Download PDF