Skip to content

firmware

ndcli firmware manages firmware tracks: staged OPNsense updates. You move devices, one by one, into the fast, regular or stable track, each track runs its update windows on a named schedule, and a release reaches fast after its own soak, and regular and stable only after it has soaked in the track before it, or when you promote it.

The firmware commands need ndcli 1.39.0 or later. An older ndcli has no firmware command.

  • An organization. Every command needs one: -o <org>, or the configured default. Without one, the CLI stops with Error: Organization is required. Use --org flag or set in config.
  • A plan that includes firmware tracks. The commands are always there, whatever your plan. A plan without the feature answers every ndcli firmware command, reads included, with Error: [FEATURE_NOT_AVAILABLE] Firmware tracks are not available on your current plan. The exception is an organization that already has a configuration: its reads, and four changes that wind it down, keep working. Check first with ndcli org quota <org>, which lists Firmware Tracks under Features.
  • A schedule for each track, created with ndcli schedule create.
  • Devices by name. device set takes device names one by one, all or nothing: an unknown device refuses the whole request. There is no OU and no pattern, and --ou isn’t a flag of any firmware command.

Every command accepts -f table, simple, detailed or json. The default is detailed, which draws boxes. The column layouts below are the -f table ones. Times follow your configured output timezone. -f json prints the control plane’s objects: wire values are lowercase (fast, managed, success), only the configuration status is ENABLED or DISABLED, and devices appear by name and UUID.

An error exits with status 1 and prints Error: [CODE] message on stderr, with a second Hint: line when there is a way forward. Under -f json the error is one object on stderr: {"error": {"code": "…", "message": "…"}}.

Five operations ask before they act, on stderr, with [y/N]: config disable, config delete, version promote, version unhalt --major and track set --auto-apply-major=true. Anything but y or yes prints Cancelled, sends nothing and exits 0. Without a terminal, they stop with Error: stdin is not a terminal — pass --force to confirm non-interactively. --force skips the question. The other commands never ask.

CommandDescription
firmware config showShow the firmware configuration and its three tracks
firmware config createEnable firmware tracks for the organization
firmware config setChange the default reboot behaviour of the update steps
firmware config enableEnable firmware tracks
firmware config disableDisable firmware tracks and release every device in a track
firmware config deleteDelete the firmware configuration
firmware track showShow the tracks, or one track
firmware track setChange a track’s soak days, minimum evidence or major upgrades
firmware track scheduleAttach a track’s update windows to a schedule, or detach them
firmware device setMove named devices into a track or back to unmanaged, or set their boot-environment setting
firmware statusShow where each device stands in the tracks
firmware historyShow a device’s firmware history
firmware rolloutShow where every release stands on its way down the tracks
firmware version haltHalt a release or a major upgrade
firmware version unhaltLift the halt on a release or a major upgrade
firmware version promoteApprove a release or a major upgrade in a track now
firmware version haltsList the halts
firmware failure clearClear the failures that block a release or a major upgrade

There is no firmware promote, firmware halt or firmware clear: those sit under version and failure.

Tracks are always fast, regular and stable. device set --track and status --track also take unmanaged, and version promote --track also takes all. The words are case-insensitive, and a wrong one is refused before anything is sent, for example Error: unknown track "bogus" — valid values: fast, regular, stable. Release and series names aren’t checked by the CLI. NetDefense decides.

Major upgrade is the CLI’s name for a series upgrade: a track moving its devices to the next OPNsense series, 26.1 to 26.7 today. See Series Upgrades. --major on halt, unhalt, promote and failure clear says that the argument is a series, not a release, because 26.7 is the name of both.


Show the firmware configuration and its three tracks.

Terminal window
ndcli firmware config show

With -f table it reads:

Organization: example-org
Status: ● Enabled
Plan: included
Reboot: yes (the full update, base and kernel included, then a reboot)
Created: 2026-10-17 10:00:00
╭─────────┬─────────┬─────────────┬────────────────┬─────────────────────────────┬────────────────────────────┬────────────────╮
│ Track │ Soak │ Min Success │ Schedule │ Next Window │ Devices │ Major Upgrades │
├─────────┼─────────┼─────────────┼────────────────┼─────────────────────────────┼────────────────────────────┼────────────────┤
│ fast │ 1 day │ 0 │ saturday-night │ 2026-10-24 02:00 (in 6d 7h) │ 2 (2 managed) │ off │
│ regular │ 9 days │ 1 │ saturday-night │ 2026-10-24 02:00 (in 6d 7h) │ 2 (1 enrolling, 1 managed) │ off │
│ stable │ 10 days │ 1 │ saturday-night │ 2026-10-24 02:00 (in 6d 7h) │ 1 (1 held) │ off │
╰─────────┴─────────┴─────────────┴────────────────┴─────────────────────────────┴────────────────────────────┴────────────────╯

Plan reads included, or not included (no new steps are sent; devices still in a track are being released) for an organization that has a configuration but lost the feature. Reboot reads yes (the full update, base and kernel included, then a reboot) or no (userland packages only; base and kernel stay deferred). Schedule is - with none, and <name> (disabled) when the schedule, or the track’s entry on it, is disabled. Next Window is -, or a time with (in 6d 7h) or (due). Updated appears after a change. Right after config disable, Releasing says how many devices are leaving their track.


Create the organization’s firmware configuration with its three tracks at their default settings. No device is in a track and no track has a schedule yet. It needs a plan that includes firmware tracks.

Terminal window
ndcli firmware config create [flags]
FlagTypeDefaultDescription
--no-rebootboolfalseMake the update steps apply the userland packages only and not reboot. By default a step applies the full update, base and kernel included, then reboots

A new configuration starts with these tracks: fast soaks 1 day and asks for no evidence, regular soaks 9 days and asks for 1 device, and stable soaks 10 days and asks for 1 device.

Creating a second configuration is refused: Error: [ALREADY_EXISTS] Firmware is already configured for organization 'example-org'.


Change whether the update steps reboot the device. It is one setting for the whole organization.

Terminal window
ndcli firmware config set --reboot
ndcli firmware config set --no-reboot
FlagTypeDescription
--rebootboolA step applies the full update, base and kernel included, and reboots
--no-rebootboolA step applies the userland packages only

Exactly one of the two is required. A series upgrade needs reboots, so it never runs while the setting is off.


Enable the configuration. Enabling does not bring any device back into a track: add them again with firmware device set.

Terminal window
ndcli firmware config enable

Disable the configuration. Every device in a track starts leaving it: its agent restores the firmware setting the device had before it joined, and the device becomes unmanaged. Devices keep the release they run, and enabling again does not bring them back.

Terminal window
ndcli firmware config disable [--force]

It asks first: Disable firmware tracks? Every device in a track will leave it and its agent will restore the firmware setting it had. [y/N]:. It still works on a plan without firmware tracks while the organization has a configuration, so that the configuration can be wound down.


Delete the firmware configuration with its tracks, the tracks’ windows on their schedules and the approvals. Halts and the history stay. Your named schedules stay too: only the tracks’ windows on them are removed.

Terminal window
ndcli firmware config delete [--force]

It asks first: Delete the firmware configuration with its tracks, schedules and approvals? This cannot be undone. [y/N]:. The prompt’s wording is broader than what happens: your named schedules stay, and only the tracks’ windows on them are removed. It is refused while any device is in a track or still leaving one. Disable firmware, or move the devices to unmanaged, and delete it once they have left:

Error: [HAS_DEPENDENCIES] Devices are still in a firmware track or leaving one; move them to unmanaged (or disable Firmware) and delete the configuration once they are released.
Devices still in a track:
• fw-branch-01

Show a track’s soak days, minimum evidence, schedule, next window, whether it applies major upgrades, and device counts. Without a track, it shows all three.

Terminal window
ndcli firmware track show [track]

Change when a track takes a release, or whether it applies major upgrades.

Terminal window
ndcli firmware track set <track> [flags]
FlagTypeDescription
--soak-daysintDays a release soaks before the track takes it. For fast it is counted from OPNsense publishing the release. For regular and stable it is counted from the release meeting its evidence in the previous track
--min-successintDistinct devices of the previous track that must have reached a release first. The fast track has no previous track, so it takes 0 only
--auto-apply-majorboolWhether the track’s windows move its devices to the next OPNsense series. =true asks first, because an upgrade takes the device offline, reboots it three times and has no automatic rollback. =false cancels the queued upgrade steps
--forceboolSkip the confirmation prompt of --auto-apply-major=true. Required when stdin is not a terminal

At least one of --soak-days, --min-success and --auto-apply-major is required. --auto-apply-major is changed on its own: with --soak-days or --min-success the CLI refuses. Soak is from 0 to 365 days and evidence from 0 to 1000 devices, and a fast track with evidence above 0 is refused with The fast track has no track before it, so it takes no evidence requirement. Releases a track has already approved stay approved. The new values apply to decisions still to come.

--auto-apply-major=true lists what an upgrade does and asks, and --force skips both the list and the question. It is off for every track by default. --auto-apply-major=false cancels the upgrade steps that were queued and not yet sent, and reports how many. An upgrade already running goes on. Turning it on needs a plan that includes firmware tracks.

Terminal window
ndcli firmware track set regular --soak-days 7 --min-success 2
ndcli firmware track set stable --soak-days 14
ndcli firmware track set fast --auto-apply-major=true
ndcli firmware track set fast --auto-apply-major=false

Run a track’s update windows on a named schedule. Create the schedule first with ndcli schedule create. Each time the schedule fires, every managed device of the track gets one update step. Tracks may share a schedule. Attaching again moves the track to the new schedule.

Terminal window
ndcli firmware track schedule <track> <schedule>
ndcli firmware track schedule <track> --no-schedule
FlagTypeDescription
--no-scheduleboolDetach the track from its schedule. It stops moving its devices

Give a schedule name or --no-schedule, but not both. A track’s schedule entry belongs to the track, so it can’t be enabled, disabled or removed with ndcli schedule tasks. Attaching needs a plan that includes firmware tracks. Detaching still works on a plan without it, while the organization has a configuration.

Terminal window
ndcli firmware track schedule fast saturday-night
ndcli firmware track schedule stable --no-schedule

Move devices, named one by one, into a track or back to unmanaged, and set their boot-environment setting. It is all or nothing for the names.

Terminal window
ndcli firmware device set <device>... [--track <fast|regular|stable|unmanaged>] [--boot-environment=<bool>]
FlagTypeDescription
--trackstringTrack to move the devices to: fast, regular, stable or unmanaged
--boot-environmentboolWhether the agent makes a ZFS boot environment before a major upgrade of the devices. On by default for a device in a track

Give --track, --boot-environment, or both.

  • A device that isn’t in a track joins it as enrolling: its agent pins it at the release it has installed, so a device never moves ahead of its track.
  • Moving a device between tracks needs no step: the pin stays where it is.
  • Moving it to unmanaged makes it leave the track: its agent restores the firmware setting the device had. That works on a plan without firmware tracks too, while the organization has a configuration. Moving devices into a track needs the plan and an enabled configuration.
  • A device whose agent is too old for firmware tracks, or that is disabled, is added but is sent nothing until that changes. The result says so.
  • --boot-environment belongs to a device’s place in a track. Give it alone for devices already in a track, or together with --track to add them with it. A device in no track has none, and it can’t be given with --track unmanaged. Changing it cancels that device’s queued major-upgrade step, if it hasn’t been sent yet. It needs a plan that includes firmware tracks.
  • There’s no confirmation prompt.
Terminal window
ndcli firmware device set fw-branch-01 fw-branch-02 --track fast
ndcli firmware device set fw-hq-primary --track unmanaged
ndcli firmware device set fw-branch-01 --boot-environment=false
ndcli firmware device set fw-branch-02 --track regular --boot-environment=false
✓ 2 devices → fast track: 2 added
╭──────────────┬────────┬───────┬───────────┬──────────┬─────────────────────────────────────────────────────────────────────────╮
│ Device │ Result │ Track │ State │ Boot Env │ Notes │
├──────────────┼────────┼───────┼───────────┼──────────┼─────────────────────────────────────────────────────────────────────────┤
│ fw-branch-01 │ added │ fast │ enrolling │ on │ │
│ fw-branch-02 │ added │ fast │ enrolling │ on │ agent too old for firmware tracks: no step is sent until it is upgraded │
╰──────────────┴────────┴───────┴───────────┴──────────┴─────────────────────────────────────────────────────────────────────────╯

Result is added, moved, unchanged, released or updated. A footer line such as 1 pending firmware step cancelled appears when the move cancelled queued steps.


List every device of the organization with its track, state, pinned release, the reason of the agent’s last hold, and the result of the last step. Unmanaged devices are listed too.

Terminal window
ndcli firmware status [flags]
FlagTypeDefaultDescription
--trackstringOnly devices in this track: fast, regular, stable or unmanaged
--statestringOnly devices in this state: enrolling, managed, held or unenrolling
--namestringOnly devices whose name contains this text
--pageint1Page number
--per-pageint50Items per page (1-200)
Terminal window
ndcli firmware status
ndcli firmware status --track regular --state managed --name fw-branch
• fw-branch-01: fast/managed, pinned 26.1.11 (series 26.1), last success 2026-10-17 02:00, major upgrade eligible, boot environment on
• fw-branch-02: regular/managed, pinned 26.1.8 (series 26.1), last held 2026-10-17 02:00, boot environment on
held: a reboot is pending on the device (held_reboot_pending)
note: major upgrade blocked by the last hold
• fw-hq-primary: regular/enrolling
note: agent too old for firmware tracks (1.23.4)
• fw-lab-bench: unmanaged
• fw-hq-secondary: stable/held, last held 2026-10-17 02:00
held: a custom firmware flavour is already set on the device (held_custom_flavour)

That is -f simple. The -f table columns are Device, Track, State, Series, Pinned, Held Reason, Last Result, Last Run, Major, Boot Env and Notes. Series, Major and Boot Env appear only when at least one row has a value for them. Last Result is one of success, noop, held, released, failed and failed_no_response. Major is eligible or blocked, and Boot Env is on or off, with (last: made), (last: skipped, no room), (last: setting was off) or (last: unavailable) once an upgrade has run. A footer such as Page 1 of 3 (showing 50 of 120 items) appears when there are more devices than one page.

Notes include agent too old for firmware tracks (1.23.4), device disabled: no step is sent while it is, the pin had been changed outside NetDefense, released automatically <time>: <reason>, major upgrade blocked by the last hold, last error: <agent text>, and what the last major upgrade found: a third-party repository, a third-party package, or both.

held is a device the agent declined to pin: it is in the track but has no pin. A step that was held for another reason leaves the device managed, and shows in the Held Reason and Last Result columns.


Show every finished firmware step of a device, newest first: the action, its outcome and reason, and the releases it moved between. A step that was a major upgrade says so, and names the series.

Terminal window
ndcli firmware history <device> [flags]
FlagTypeDefaultDescription
--pageint1Page number
--per-pageint50Items per page (1-200)
╭──────────────────┬───────┬─────────┬───────┬─────────┬───────────────────────────────────┬─────────┬──────────────────┬─────────┬───────╮
│ When │ Track │ Action │ Kind │ Outcome │ Reason │ Target │ Versions │ Applied │ Notes │
├──────────────────┼───────┼─────────┼───────┼─────────┼───────────────────────────────────┼─────────┼──────────────────┼─────────┼───────┤
│ 2026-10-17 02:04 │ fast │ advance │ major │ success │ the update was applied │ 26.7 │ 26.1.11 → 26.7 │ yes │ │
│ 2026-10-10 02:01 │ fast │ advance │ minor │ success │ the update was applied │ 26.1.11 │ 26.1.8 → 26.1.11 │ yes │ │
│ 2026-10-03 02:00 │ fast │ advance │ minor │ held │ a reboot is pending on the device │ 26.1.9 │ 26.1.8 │ no │ │
│ 2026-09-30 02:00 │ fast │ enroll │ minor │ success │ pinned at the installed release │ - │ → 26.1.8 │ no │ │
╰──────────────────┴───────┴─────────┴───────┴─────────┴───────────────────────────────────┴─────────┴──────────────────┴─────────┴───────╯
Total: 4 step(s) for fw-branch-01

Action is enroll, advance or unenroll, and Kind is minor or major, shown only on a page that has a major step. Outcome is one of success, noop, held, released, failed and failed_no_response. Notes says when a failure was cleared, and by whom. A step that ended without an answer, such as one that expired because the device was offline, leaves no entry.


Show where every release stands on its way down the tracks.

Terminal window
ndcli firmware rollout

For each track and OPNsense series it shows the release the track moves its devices to (the target), the next release it will take, the soak left on it (counted by NetDefense), the evidence reached against the one required, and whether it has stalled. Below, the failures that block a release and the halts in force. Then the major upgrades, per track and series: where each stands (soaking, waiting for evidence, approved, halted, or path closed while OPNsense’s upgrade files aren’t open), whether the track applies it, how many devices are eligible, already on the series, or upgraded by a track, what blocks it, and the failures that block a series in the later tracks. Last comes the check of NetDefense’s own package repository, for the FreeBSD versions an upgrade crosses.

The release table has the columns Track, Series, Target, Next, State, Soak Left, Evidence and Notes. Target marks a release an operator promoted with (manual). State is ready for the next window, soaking, waiting for the previous track, waiting for evidence or blocked by a failure. A stall reads stalled: too few devices in the previous track can still reach it; add devices or lower min success, or stalled: an unresolved failure blocks it; see the failures, then 'ndcli firmware failure clear'.

The major-upgrade table has Track, Series (26.1 → 26.7), State, Soak Left, Evidence, Apply (on or off), Eligible, On Series, Upgraded and Notes. Its states add path closed, halted, approved and approved, not applied, which is approved while the track’s switch is off. When a major upgrade doesn’t start, Notes gives the reason: for example that major upgrades are switched off on this deployment, that reboot is off in the configuration, that every device of the track runs an agent too old for major upgrades, that OPNsense’s upgrade path is closed, that the track has not approved the last release of the current series yet, that no device of the track is on the last release of its series yet, or that devices are waiting for the ordinary window that records it.


Halt a release. No track approves it, and the steps queued for it that haven’t been sent yet are cancelled. Devices already on it stay on it: there is no rollback. The release must be one NetDefense already knows from OPNsense’s mirror.

Terminal window
ndcli firmware version halt <version|series> --reason <text> [--major]
FlagTypeDescription
--reasonstringWhy the release or major upgrade is halted. Plain text, one line. Required
--majorboolThe argument is the target series of a major upgrade, such as 26.7, not a release

With --major, no track approves the upgrade, and the upgrade steps queued for it that haven’t been sent are cancelled. Devices already upgrading are left alone, and devices already on the series stay on it. The series must be the target of a supported upgrade. There’s no confirmation prompt.

Terminal window
ndcli firmware version halt 26.7.5 --reason "regression in the VPN stack"
ndcli firmware version halt 26.7 --major --reason "the upgrade payload changed"

Lift the halt on a release. It competes for the tracks again, under the soak and evidence they ask for.

Terminal window
ndcli firmware version unhalt <version|series> [--major] [--force]
FlagTypeDescription
--majorboolThe argument is the target series of a major upgrade
--forceboolSkip the confirmation prompt of --major. Required when stdin is not a terminal

Lifting the halt on a release asks nothing. Lifting the halt on a major upgrade asks, because a track with major upgrades on that has approved it then upgrades every device that passes the checks at its next window: offline for the length of the upgrade, three reboots, no automatic rollback.


Approve a release in one track, or in all three at once, without waiting for its soak. It is the way an urgent security release goes out: every device of a track that approved it installs it at the track’s next window. It is idempotent. The release must be one NetDefense knows, it must not be halted, and the configuration must be enabled.

Terminal window
ndcli firmware version promote <version|series> --track <fast|regular|stable|all> [--major] [--force]
FlagTypeDescription
--trackstringTrack to approve the release in: fast, regular, stable or all. Required
--majorboolThe argument is the target series of a major upgrade
--forceboolSkip the confirmation prompt. Required when stdin is not a terminal

It always asks first, for a release and for a series. With --major, approving starts no upgrade by itself. A track with major upgrades on then upgrades every device that passes the checks at its next window. The series must be the target of a supported upgrade, it must not be halted, and OPNsense’s upgrade path for it must be open (FIRMWARE_UPGRADE_NOT_OPEN otherwise).

Terminal window
ndcli firmware version promote 26.7.5 --track all
ndcli firmware version promote 26.7.5 --track fast
ndcli firmware version promote 26.7 --major --track fast
✓ Release 26.1.11 approved in fast, regular without waiting for its soak
╭─────────┬──────────────────┬────────────╮
│ Track │ Result │ Target Now │
├─────────┼──────────────────┼────────────┤
│ fast │ approved now │ 26.1.11 │
│ regular │ approved now │ 26.1.11 │
│ stable │ already approved │ 26.1.11 │
╰─────────┴──────────────────┴────────────╯

List the halts of the organization, newest first. By default only the halts in force, and only those of releases.

Terminal window
ndcli firmware version halts [flags]
FlagTypeDefaultDescription
--allboolfalseAlso list the halts that have been lifted
--kindstringreleases onlyWhich halts to list: minor, major or all
--pageint1Page number
--per-pageint50Items per page (1-200)

--kind major lists the halts of major upgrades instead, each with its series, and --kind all lists both, told apart by their kind.


A failed update step blocks the release it was moving a device to from reaching the next track, until the same device later reaches it or you clear the failure. Clearing lets the release move on. The records stay in the history.

Terminal window
ndcli firmware failure clear <version|series> [--track <track>] [--major]
FlagTypeDefaultDescription
--trackstringevery trackLimit to one track: fast, regular or stable
--majorboolfalseThe argument is the target series of a major upgrade

With --major, a failed upgrade, or one that never answered, blocks the series in the later tracks only. After a manual rollback of a device, clear the failures it caused once the device is re-bound. There’s no confirmation prompt.

Terminal window
ndcli firmware failure clear 26.7.4
ndcli firmware failure clear 26.7 --major --track fast

ndcli firmware status, history and task describe show a reason as a sentence. -f simple and -f detailed add its code in brackets.

CodeSentence
appliedthe update was applied
enrolledpinned at the installed release
unenrolledthe original firmware setting was restored
at_or_above_targetalready at or above the target release
target_not_yet_offeredthe target release is not on the device’s mirror yet
series_not_approvedno release is approved for the device’s series
pin_driftthe pin was changed outside NetDefense
major_offereda major upgrade is offered; the device stays on its release
held_check_failedthe firmware check failed
held_release_folder_missingthe release folder is missing on the device’s mirror
release_folder_unavailablethe release folder is gone from the device’s mirror
held_downgrade_riskthe update would downgrade packages
held_unsupported_editionthe device has a subscription or an edition that firmware tracks do not support
held_custom_flavoura custom firmware flavour is already set on the device
held_firmware_busyanother firmware operation was running
held_unexpected_planthe update plan was not what the track expected
held_reboot_pendinga reboot is pending on the device
held_test_modethe agent is in test mode and does not move firmware
held_late_dispatchthe step reached the device with less time left than the update needs
held_insufficient_spacethe device has too little free disk space for the major upgrade
held_ha_memberthe device is a member of an HA pair, and a major upgrade is held for one
held_agent_abi_unavailableno usable NetDefense repository for the new FreeBSD version (the url is not ABI-nested, the host is unreachable, or the tree is missing)
held_upgrade_aborteda major upgrade attempt aborted before it changed the device, or the agent is waiting before trying again
dead_manno contact for 30 days

dead_man is the 30-day rule: the device was moved to unmanaged because it had no contact for 30 days. See Limits. major_offered comes from agent 1.24.0, which holds a step when a major upgrade is on offer. Agent 1.25.0 no longer reports it.

A code the CLI doesn’t know is shown as the code itself. What each means, and what to do, is in Troubleshooting.

A refusal keeps its [CODE] and message, and some add a Hint: line.

CodeWhenHint or next step
FEATURE_NOT_AVAILABLEThe plan doesn’t include firmware tracksCheck ndcli org quota <org>
FIRMWARE_NOT_CONFIGUREDFirmware is not configured for organization 'example-org'.Create the firmware configuration first: 'ndcli firmware config create'.
FIRMWARE_DISABLEDFirmware is disabled for this organization; enable it before adding devices to a track.Enable it first: 'ndcli firmware config enable'.
HAS_DEPENDENCIESconfig delete while devices are in a track or leaving oneDisable firmware or move the devices to unmanaged first
FIRMWARE_DEVICE_LEAVINGThese devices are still leaving their firmware track; add them again once they are released: …Check progress with 'ndcli firmware status', and add the device again once it has left its track.
FIRMWARE_DEVICE_MANAGEDA manual firmware upgrade for a device in a trackTake the device out of its track first
FIRMWARE_SPEC_MANAGEDDeleting a schedule that carries a track’s window, or enabling, disabling or removing the track’s own entry with ndcli schedule tasksDetach the track first
FIRMWARE_UPGRADE_NOT_OPENPromoting a series whose upgrade path is closedSee ndcli firmware rollout
FIRMWARE_VERSION_UNKNOWNRelease 26.9.9 is not in the release catalog. or Series 26.7 is not a supported series upgrade.
FIRMWARE_VERSION_HALTEDPromoting a halted release or seriesLift the halt before promoting it
  • Tasks. A track’s step is a task of type FIRMWARE_TRACK. NetDefense creates it, never a client: ndcli run can’t. List them with ndcli task list --type FIRMWARE_TRACK. A page that holds a completed one gets a Result column, such as advance success 26.1.11 → 26.7 (major upgrade) or advance held — a reboot is pending on the device. ndcli task describe <task> prints a Firmware track result block, and -f json adds it as firmware_track_result beside the raw message. A task that isn’t completed shows its plain Message.
  • Schedule entries. A track’s window is a schedule entry of kind FIRMWARE. ndcli schedule tasks list shows it as fast track window, and -f json carries firmware_track. ndcli schedule tasks remove on it is refused locally, and enable and disable are refused by the server. Detach the track instead, or move it to another schedule.
  • Deleting a schedule. A schedule that a track runs on can’t be deleted. ndcli schedule delete refuses, names the tracks, and tells you to detach each with ndcli firmware track schedule <track> --no-schedule first.
  • ndcli run firmware-upgrade. A device in a track, in any state, is refused: Error: [FIRMWARE_DEVICE_MANAGED] These devices are in a firmware track, which moves them between releases; move them out of their track to run a firmware upgrade on them: fw-branch-01, with a hint to use ndcli firmware status and ndcli firmware device set <device> --track unmanaged. See run firmware-upgrade.
  • Not in device list. ndcli device list and describe don’t show a device’s track. ndcli firmware status does.

Each command has a tool in the MCP server, 18 in all. Their arguments follow the command’s flags, with an optional organization.

ToolCommandAsks for confirm=true
ndcli.firmware.config_showfirmware config show
ndcli.firmware.config_createfirmware config create, with reboot (true by default)
ndcli.firmware.config_updatefirmware config set, with rebootyes
ndcli.firmware.config_enablefirmware config enable
ndcli.firmware.config_disablefirmware config disableyes
ndcli.firmware.config_deletefirmware config deleteyes
ndcli.firmware.track_showfirmware track show
ndcli.firmware.track_setfirmware track set, with soak_days, min_success, auto_apply_majoryes
ndcli.firmware.track_schedulefirmware track schedule, with schedule or no_scheduleyes
ndcli.firmware.device_setfirmware device set, with devices, track, boot_environmentyes
ndcli.firmware.statusfirmware status
ndcli.firmware.historyfirmware history
ndcli.firmware.rolloutfirmware rollout
ndcli.firmware.version_haltsfirmware version halts, with kind and all
ndcli.firmware.version_haltfirmware version halt, with kind=major for a seriesyes
ndcli.firmware.version_unhaltfirmware version unhaltyes
ndcli.firmware.version_promotefirmware version promoteyes
ndcli.firmware.failure_clearfirmware failure clearyes

The MCP tools are stricter than the CLI. The CLI asks for five operations. Over MCP, the ten tools marked above change nothing until they are called with confirm=true, and return a preview instead. config_create and config_enable run at once on both surfaces. Turning major upgrades on previews the consequences, with a note to show them to the operator and ask for a go-ahead before calling again with confirm=true. Where the CLI uses --reboot and --no-reboot, the tools use reboot, true meaning reboot. A series is version with kind=major, where the CLI uses --major. Refusals name tools in their hints, for example Create the firmware configuration first: ndcli.firmware.config_create.