Upgrade your installation
NetFoundry Self-Hosted provides a guided, interactive upgrade script that walks through upgrading each component one at a time. Each component can be individually skipped, so you can upgrade only what you need.
Before you upgrade
Always upgrade the controller before the routers. Routers running versions below 1.7 will fail to connect after a controller upgrade. The upgrade script warns you if incompatible routers are detected before proceeding.
Before starting an upgrade:
- Check cluster health: Run
nf-statusand verify all pods are running and healthy. - Review the changelog: Check the release notes for breaking changes or required manual steps.
- Consider backups: The upgrade script automatically takes a local database snapshot before upgrading the controller, but for disaster recovery you should also have Velero/S3 backups configured.
- Update the package: Install the new version of
netfoundry-self-hostedbefore running the upgrade. The package includes an updated.envfile with tested, compatible Helm chart versions.
Run the upgrade
nf-upgrade
The script is fully interactive by default. It prompts you before each component and any component can be skipped by answering "n" at the prompt.
To upgrade specific components without prompts, use the component flags:
nf-upgrade --controller --router
When component flags are provided, only the specified components are upgraded and all prompts are automatically accepted.
Command reference
nf-upgrade [-y] [-S] [--controller] [--router] [--ziti-host] [--support] [--console] [--zlan] [--k3s] [--skip-snapshot]
| Flag | Description |
|---|---|
-y | Non-interactive mode—accept all prompts |
-S, --skip-snapshot | Skip the automatic pre-upgrade database snapshot |
--controller | Upgrade the controller |
--router | Upgrade the edge router |
--ziti-host | Upgrade the ziti-host tunneler |
--support | Upgrade the support stack |
--console | Upgrade (or install) Ziti Console Enterprise |
--zlan | Upgrade the zLAN Console |
--k3s | Upgrade K3s |
Examples:
nf-upgrade # Interactive—prompt for each component
nf-upgrade -y # Upgrade all components, no prompts
nf-upgrade --controller # Upgrade only the controller
nf-upgrade --controller --router # Upgrade controller and router only
nf-upgrade --controller --skip-snapshot # Upgrade controller, skip the snapshot
nf-upgrade --console # Upgrade or install Ziti Console Enterprise
Run nf-status before and after the upgrade to confirm everything is healthy.
What the upgrade does
The upgrade script walks through components in this order:
1. Controller
- Displays the currently running controller version.
- Takes an automatic snapshot of the BoltDB database (via
nf-create-snapshot). - Detects major Helm chart version crossings and runs the appropriate upgrade hook automatically (for example,
the v2→v3 hook handles PKI consolidation and
cluster.modeinjection). - Runs
helm upgradefor theziti-controllerchart. - Displays the new controller version after the upgrade completes.
The automatic pre-upgrade snapshot gives you a restore point if something goes wrong. You can also take manual
snapshots at any time with nf-create-snapshot.
2. Edge router
- Displays the currently running router version.
- Runs
helm upgradefor theziti-router-1chart. - Displays the new router version after the upgrade completes.
3. ziti-host
- Only offered if a helm-managed
ziti-hostdeployment exists in thesupportnamespace. - Displays the current version and runs
helm upgradefor theziti-hostchart.
4. Support stack
- Detects major support chart version crossings and runs the appropriate upgrade hook automatically.
- Replicates the controller admin secret into the
supportnamespace, and the Elasticsearch credentials and CA into thebeatsnamespace, so the telemetry connector and the Beats agents can authenticate. - Upgrades the NetFoundry support Helm chart.
Migrating a v1 support stack to v2 (2.0.0)
Upgrading to 2.0.0 crosses the support chart's v1→v2 boundary and runs the "full collapse" migration: Logstash,
RabbitMQ, Redis and the Ziti Metrics Processor are removed, and nf-data-connector replaces them as the single
telemetry path. nf-upgrade summarises this and asks before changing anything:
Do you want to proceed with the support stack "full collapse" migration upgrade? [Y/n]:
Answering n leaves your v1 stack running and continues with the rest of the upgrade. The full inventory of what
is removed and added is in the changelog.
Your existing ziti.<namespace> indices are not deleted or reindexed — they age out under their current ILM policy
while the connector writes new ziti.* data streams alongside them.
Two things need your attention:
- Registry credentials. The connector pulls a private image, so
REGISTRY_USERNAMEandREGISTRY_PASSWORDmust be available (air-gapped installs use preloaded images and need neither). - A controller carrying the retired AMQP event logger. The migration never edits your controller. If the
configuration is in your own
controller-values.yml, the upgrade prints anACTION NEEDEDnotice naming the exact keys to delete; follow it and runnf-upgrade --controller. Your network is not at risk in the meantime — the controller drops those events.
nf-upgrade -y, and any run passing component flags such as --support, accepts the migration prompt
automatically. Run nf-upgrade interactively for your first 2.0.0 upgrade so you can read the summary first.
Upgrade the zLAN Console too (nf-upgrade --zlan): its post-upgrade job repoints the logstash.zfw OpenZiti
service to the connector. Until you do, the zfw sensor keeps dialling the removed Logstash and its data does not
arrive. The service and config names keep the logstash prefix so existing sensors need no reconfiguration.
5. Ziti Console Enterprise
- Only offered if
--consoleis passed or in interactive mode. - If Ziti Console Enterprise is already installed, upgrades it in place.
- If it's not installed, offers to install it. Requires NetFoundry container registry credentials
(
REGISTRY_USERNAMEandREGISTRY_PASSWORD).
6. zLAN Console
- Only offered if the
zlan-consoleHelm release is already installed. - Runs
helm upgradefor thezlan-consolechart.
Version management
Helm chart versions are pinned in the .env file at the root of the installation directory:
| Variable | Controls | Example |
|---|---|---|
HELM_CHART_VERSION_CTRL | ziti-controller chart version | 3.3.0 |
HELM_CHART_VERSION_ROUTER | ziti-router chart version | 3.0.2 |
HELM_CHART_VERSION_ZITI_HOST | ziti-host chart version | ^1.4.0 |
HELM_CHART_VERSION_CERT_MANAGER | cert-manager chart version | v1.19.1 |
HELM_CHART_VERSION_TRUST_MANAGER | trust-manager chart version | ^0.18.0 |
The OpenZiti application version (the version of OpenZiti software running inside the containers) is determined by
the helm chart's appVersion. By default, upgrading a Helm chart also upgrades the OpenZiti application to the version
bundled with that chart. This is the recommended approach, as each chart version is tested against a specific OpenZiti
version.
If you need to pin or override the OpenZiti application version independently of the chart, set the image.tag field in
your values file. For example, in controller-values.yml:
image:
tag: "1.6.12"
Or in router-values.yml:
image:
tag: "1.6.12"
When image.tag is set, Helm will use that specific container image tag instead of the chart's default appVersion.
To return to the chart default, remove the image.tag override or set it to an empty string.
When you install a new version of the netfoundry-self-hosted package, the .env file is updated with tested,
compatible chart versions. This is the primary mechanism for ensuring version compatibility across components.
Offline / air-gapped upgrades
Offline upgrades use the same tarball as the initial installation. The new tarball contains updated Helm charts, container images, scripts and system packages.
1. Transfer the new tarball
On a machine with internet access, download the new offline tarball using your JFROG credentials and transfer it to the air-gapped host.
2. Extract over the existing installation
tar -zxf ./netfoundry-self-hosted-offline-<version>.tar.gz -C /opt/netfoundry/self-hosted
Extracting adds and overwrites files; it does not remove anything. nf-upgrade reconciles the install directory
against the bundle in the next step, deleting files the new release no longer ships.
Your own files — controller-values.yml, router-values.yml, support-values.yml, controller-vars.sh,
.checkpoints/ — are never touched by either step.
3. Run the upgrade
nf-upgrade
Or non-interactively, for all components or specific ones:
nf-upgrade -y
nf-upgrade --controller --router
Offline mode is auto-detected from the presence of packages/offline-helm-charts/ — no manual
export OFFLINE_MODE=true is needed. The upgrade imports the bundled container images into K3s, resolves Helm
charts from the local directory, and upgrades the packages and CLI tools the bundle ships, including the ziti
CLI. It then records what the bundle installed in .installed/, which is how the next upgrade knows which files to
remove.
Before changing anything, the upgrade renders every chart it is about to apply. If one cannot render, it stops with nothing modified.
The controller must be upgraded before the routers. The upgrade script enforces this order automatically.
Run nf-status after the upgrade. It lists the chart and application version of every release and warns if one does
not match the version the bundle ships.
Upgrading to 2.0.0
The upgrade may print an ACTION NEEDED notice about RabbitMQ/AMQP configuration on your controller. This happens
when controller-values.yml carries the retired AMQP event-logger settings, which point at a RabbitMQ that 2.0.0
removes. The upgrade does not edit your values file. The notice names the three keys to delete —
additionalConfigs, env and envSecrets — and gives a command to check the result. Apply it with:
nf-upgrade --controller
Until you do, the controller retries a RabbitMQ that is no longer there. Telemetry is unaffected: it flows through
nf-data-connector.
The rabbit-password secret in the ziti namespace is kept while your controller still references it — the
controller cannot start without it. Delete it once you have removed those keys and re-run the controller upgrade:
kubectl delete secret rabbit-password -n ziti
Backup and recovery
The upgrade script automatically takes a BoltDB snapshot before upgrading the controller. You can also take one manually at any time:
nf-create-snapshot
Restore from snapshot
To restore the controller database from a snapshot:
nf-restore-snapshot
The restore script will:
- List available snapshots and let you choose one.
- Temporarily stop the controller (this disrupts network services).
- Replace the database file with the selected snapshot.
- Restart the controller.
Velero backups
For full cluster backup and disaster recovery, configure automated Velero backups to S3. See the backups documentation for setup instructions.
Rollback
Some upgrades—particularly major Helm chart version changes—involve one-way operations such as PKI restructuring
or database migrations. A standard helm rollback won't undo these changes. Instead, use the following approach.
Step 1: Roll back the application version
Pin the previous OpenZiti version by setting image.tag in your values file. For example, in controller-values.yml:
image:
tag: "1.6.8"
Then re-apply the Helm chart:
helm upgrade --install ziti-controller openziti/ziti-controller \
-n ziti --values ./controller-values.yml \
--wait --timeout 180s
Run nf-status to verify the pods are running with the expected version.
Step 2: Restore from snapshot (if needed)
If rolling back the image tag isn't sufficient—for example, if a database migration in the new version is incompatible with the older binary—restore the pre-upgrade database snapshot:
nf-restore-snapshot
This will:
- List available snapshots (the most recent one is the automatic pre-upgrade snapshot).
- Stop the controller, replace the database with the selected snapshot, and restart it.
Restoring a snapshot reverts all controller state (identities, policies, services, etc.) to the point when the snapshot was taken. Any changes made after the snapshot will be lost.
Skipping the pre-upgrade snapshot
If you're making multiple upgrade attempts in a row and don't need a new snapshot each time, pass
-S or --skip-snapshot to skip the automatic snapshot:
nf-upgrade --controller --skip-snapshot
This only skips the automatic pre-upgrade snapshot. It doesn't affect the upgrade itself.