Reference / CLI
upgrade
kix upgrade moves a project to a newer version of Kix. It builds every
cluster with the version the project uses now, pins the project to the new
version, and builds every cluster again. Then it compares the two builds and
lists the release notes that apply to the project.
kix upgrade runs in the Kix version you invoke directly, even when
kix.toml pins an older version. For each version it tests, it installs that
version of Kix if needed and runs the build with it. It does not contact any
cluster.
Synopsis
Section titled “Synopsis”1kix upgrade [--to <VERSION>] [--preview]2kix upgrade --ack <ID>...| Flag | Default | Description |
|---|---|---|
--to <VERSION> | latest | The version to move to: an exact version such as 0.10.2, a minor such as 0.10 (its newest patch), or latest, the newest release that is not a prerelease. |
--preview | false | Print what the upgrade would do and the release notes that apply, and change nothing. |
--ack <ID>... | none | Acknowledge a change to stored data by its id or name, so that kix deploy goes ahead. Does nothing else. |
The version the project uses
Section titled “The version the project uses”kix upgrade starts from the exact version in kix.toml, such as
kix = "0.9.1". When kix.toml names a minor or no version, it starts from
the version of the project’s Kix library in flake.lock. When the target is
not newer than that, it prints this and exits 0:
1Already on the latest Kix release (0.12.1). Nothing to upgrade.Release notes
Section titled “Release notes”Every release of Kix publishes structured release notes beside its release
archives, as kix-<version>-changes.json, listed in the release’s signed
SHA256SUMS. kix upgrade fetches the notes of every release after the
project’s version up to the target and checks each file against
SHA256SUMS. A release made before structured release notes existed has
none, and the first run of an upgrade says so:
1Note: Kix 0.9.1 has no release notes; see CHANGELOG.md.kix upgrade --preview lists every breaking, security, and upgrade note in
the range, and every release that every cluster must deploy, grouped by what
you must do. Added, changed, and fixed notes are counted. It changes
nothing:
1Kix 0.10.0 -> 0.12.1 (preview, no files changed)2
36 changes between 0.10.0 and 0.12.1:4 * may affect your 6 clusters (package name matches an instance in use)5
6 Config changes required (will fail the build until updated):7 * [K0003] caddy (0.11.0): `replicaCount` was renamed to `replicas`.8 [K0005] echo-server (0.11.0): `port` was renamed to `servicePort`.9
10 Behavior & data changes (builds cleanly, requires review before deploy):11 [K0009] (0.11.0): Cluster-wide default network policy mode now drops12 unmatched egress traffic in namespaces with at least one workload.13 * [K0007] harbor (0.12.0, moves stored data): Registry blob metadata moved14 to v2 layout; existing PVCs are migrated in place on first start.15 Requires `kix upgrade --ack K0007` before `kix deploy`.16
17 Security fixes (builds cleanly, recommended for this upgrade):18 * [K0008] caddy (0.11.2, CVE-2026-4102): Fixes HTTP/2 CONTINUATION frame19 flood.20 Without upgrading: Set `caddy.http2 = false` in the cluster.21
22 Notes:23 * [metrics-port] caddy (0.11.2): Admin metrics endpoint now binds to24 127.0.0.1:2019 by default.25
26 14 minor feature and bugfix changes between 0.10.0 and 0.12.1 are not shown (see CHANGELOG.md).27
28`kix upgrade` will stop for [K0003], [K0005] until you make the config changes above.29Next: run `kix upgrade`.A note names packages, and Kix sees only the instance names a cluster uses
(from kix list packages --cluster <name>, run with the project’s current
Kix). So Kix cannot tell which notes affect a project. It lists them all,
and marks with * a note whose package name equals the name of an instance
in use. An unmarked note can still affect an instance with another name.
When the current Kix is not installed, the preview marks nothing. When the
range has no breaking, security, or upgrade notes, it says
No breaking, security, or upgrade notes between 0.10.0 and 0.12.1.
What a run does
Section titled “What a run does”-
Builds every cluster with the version the project uses now, with
kix export <cluster> --for audit, into~/.cache/kix/upgrade/<project>/before/. When a cluster does not build, it stops with exit status2. Fix the project on its current version first. -
Pins the project to the target, installs it, and builds every cluster. Pinning writes the exact version into
kix.tomland moves the Kix library inflake.lockaskix lib updatedoes. When the library input inflake.nixnames the project’s version as a tag, such asgithub:kix-run/kix/v0.9.1,?ref=refs/tags/v0.9.1, or?ref=v0.9.1on any host, Kix moves that tag too, but only when exactly one Kix URL inflake.nixnames it. When two or more do, such as a second input that pins a version of Kix built into an image, Kix changes nothing, names the lines, writesedit-neededintokix-upgrade.json, and exits3before it installs the target. Change the library input’s URL yourself, leave the others, and runkix upgradeagain. When Kix cannot lock the new tag inflake.lock, orflake.lockstill names another tag afterwards, Kix putskix.toml,flake.nix, andflake.lockback as they were before that step, names the tag, and exits2or3. -
When a cluster does not build with the target, takes one minor release at a time: the newest patch of each minor after the project’s, ending with the target. A project on a prerelease, such as
0.9.0-rc.1, takes the newest release of its own minor first. It stops at the first release a cluster does not build with, prints the end of each error and that release’s matching config changes, keeps each cluster’s full build output in a log file, leaves the project pinned to that release, and exits2:1Building 6 clusters with Kix 0.12.1... failed (lt1)2Stepping one minor release at a time (0.11.2 -> 0.12.1):3Building 6 clusters with Kix 0.11.2... failed (1 of 6 failed: lt1)45Cluster lt1:6error: The option `packages.caddy.replicaCount` does not exist.7Full build log: ~/.cache/kix/upgrade/<project>/logs/0.11.2/lt1.log89Matching change in Kix 0.11.0:10[K0003] caddy: `replicaCount` was renamed to `replicas`.1112Stopped at Kix 0.11.2 (step 1 of 2 toward 0.12.1).13kix.toml, flake.nix, and flake.lock are pinned to 0.11.2 so you can fix this step first.14Next: fix the error above, then run `kix upgrade` to continue to 0.12.1.Fix the errors against that release, then run
kix upgradeagain. The next run reuses the builds from step 1 and the package list made then, tries that release again, and continues. So does a run after an interruption, since Kix writeskix-upgrade.jsonbefore it first pins the project. If the cached builds from step 1 are missing, Kix stops with an error. Deletekix-upgrade.jsonand runkix upgradeagain; the comparison then starts from the version the project is pinned to now. -
Compares the first build with the last, cluster by cluster, and prints the objects added, removed, and changed. Clusters that changed the same way are printed together, with
+,~, and-for added, changed, and removed objects. A change is marked[review: <Kind>]when the object is a Secret, Role, ClusterRole, RoleBinding, ClusterRoleBinding, NetworkPolicy, CiliumNetworkPolicy, CiliumClusterwideNetworkPolicy, or Certificate, or an Ingress or Gateway whose TLS settings changed. -
Searches the files git tracks in the project for each command or flag a release note says was removed or changed, and prints
file:linefor each. It skipsflake.lock,CHANGELOG.md,changes/, and files over 1 MB. -
Removes each version of Kix it installed only to build with, keeping the version the project used and the version it is now pinned to. It says so only with
-v. -
Writes
kix-upgrade.jsonin the project, and ends with what to review before you deploy:1Upgraded to Kix 0.12.1, but review before deploying:21. 3 Secrets changed in cluster xdi1 (Secret/harbor-core@registry,3Secret/harbor-exporter@registry, Secret/harbor-jobservice@registry).42. 5 objects changed in clusters lt1, xdi1; read the changes above, or run5`kix diff <cluster>`, before you deploy.63. [K0007] moves stored data in harbor. Once you are ready for the7migration, unblock deploy with:8kix upgrade --ack K0007Any object that changed in any cluster is on this list, and the run exits
3. Only when no object changed and nothing needs a review does it end withUpgraded to Kix 0.12.1. Ready to deploy.and exit0.
When a release between the project’s version and the target has a change
that every cluster must deploy before it upgrades further, the upgrade ends
at the newest patch of that release’s minor, and exits 3:
1Upgraded to Kix 0.11.2, but review before deploying:2 1. Kix 0.11.0 must be deployed to all clusters before continuing to 0.12.13 (`kix deploy` on 0.12.1 will refuse any cluster still on 0.10.0).4 kix.toml, flake.nix, and flake.lock are pinned to 0.11.2.5Next: commit this 0.11.2 step and deploy every cluster with `kix deploy <cluster>`, then run `kix upgrade` to continue to 0.12.1.kix deploy refuses a
cluster that would skip the release.
Changes to stored data
Section titled “Changes to stored data”A change that moves or reinterprets stored data with no error goes into
kix-upgrade.json. Until someone acknowledges it, kix deploy refuses to
run, prints the note, and names the command:
1Deploy blocked: upgrade to Kix 0.12.1 includes an unacknowledged data migration.2No clusters were contacted.3
4 [K0007] (0.12.0, moves stored data):5 Registry blob metadata moved to v2 layout; existing PVCs are migrated in6 place on first start.7
8Next: once you are ready for this migration, run:9 kix upgrade --ack K000710Then run `kix deploy` again.kix upgrade --ack K0007 records the acknowledgement in
kix-upgrade.json:
1Acknowledged K0007 in kix-upgrade.json. You can now run `kix deploy`.kix deploy --dry-run and kix plan are not blocked.
Another kix upgrade also refuses until each change is acknowledged.
This check reads kix-upgrade.json, so it protects only a project that was
upgraded with kix upgrade and kept the file. A project whose pins were
moved by hand gets no refusal. Commit kix-upgrade.json with the upgrade.
kix-upgrade.json
Section titled “kix-upgrade.json”| Field | Meaning |
|---|---|
schema | kix.run/upgrade/v1 |
from, to | The version the upgrade started from, and the version it moved to. |
status | done, fix-needed (a build failed, or the run stopped part of the way), edit-needed (a person must edit flake.nix), needs-person, or required-stop. |
steps | Each version the project was built with: version, result (ok, failed, or started for a step that stopped before it built), and failed, the clusters that did not build. |
records | The ids (or names, for a note without an id) of the release notes that apply, by kind. |
dataChanges | The changes to stored data: reference, release, and body. |
acknowledged | The data changes someone acknowledged with --ack. |
sensitiveChanges | How many changed objects are sensitive. |
cliHits | Each project line that uses a changed command or flag: text, file, line. |
before | The directory of the builds made with the version the upgrade started from. |
packagesInUse | The instances the project’s clusters install, as the version the upgrade started from listed them. Absent when Kix could not list them. |
Programs that read the file must skip fields they do not know.
Environment
Section titled “Environment”| Variable | Effect |
|---|---|
KIX_RELEASE_SOURCE | A site laid out like kix.run to fetch releases from, such as an internal mirror. See kix self. |
XDG_CACHE_HOME | The builds go under $XDG_CACHE_HOME/kix/upgrade/ in place of ~/.cache/kix/upgrade/. |
Exit status
Section titled “Exit status”0when the project builds with the target, no object changed in any cluster, and nothing needs a person, and with--previewor--ack.1when the release index or a release’s notes cannot be fetched or verified, a version cannot be installed, or the project cannot be pinned.2when a cluster does not build, with the version the project used or with a release the upgrade tried.3when the project builds with the target and a person should read what changed: an object that changed in any cluster, a sensitive object change, a behavior or data change, or a release that every cluster must deploy first.