Skip to content
Install the CLI

How-to guide Adopt existing resources

Handle stateful migration prompts safely

Kix stops a deployment when one stateful resource replaces another in the same package slot. Treat this prompt as a data-migration gate.

The migration gate applies only when one stateful resource replaces another. If a stateful resource is removed without a replacement, Kix treats it as an ordinary orphan. Running with --prune deletes it without a migration prompt. See Deploy with dry-run, timeouts, pruning, and log/TUI output modes to see how the plan reports orphans before deletion.

The example changes the data/volume package from PersistentVolumeClaim/media-v1 at 5Gi to PersistentVolumeClaim/media-v2 at 10Gi.

Review the pair before contacting the cluster

Section titled “Review the pair before contacting the cluster”

This example exports the current definition with its Kix provenance so it can stand in for the old side of an offline diff:

kix-examples/
❱ kix export how-to-stateful-migration --for audit --out stateful-before
Building cluster 'how-to-stateful-migration'...
  Evaluating cluster 'how-to-stateful-migration'...
  Reading package index...
  Loading store graph...
  Reading 3 packages...
  Computing cross-package dependencies...

  Exported 9 resources to stateful-before (audit (kix provenance preserved))

Compare the replacement definition with that saved state:

kix-examples/ output excerpt offline capture
❱ kix diff how-to-stateful-migration --from stateful-before
Show outputHide output · 9 lines
+ PersistentVolumeClaim/media-v2@data
- PersistentVolumeClaim/media-v1@data
Stateful workload replacements (1):
data/volume (size changed: 5Gi -> 10Gi):
- PersistentVolumeClaim/media-v1@data
+ PersistentVolumeClaim/media-v2@data
Data migration is not automated: Kix does not copy data, and PersistentVolumeClaim/media-v2@data sees only data already present in its storage.
`kix deploy` requires `--accept-migrations`.
(exit code: 2)

Check the logical slot, source, target, and reason. Kix reports this pair because both resources have lifecycle = "stateful", occupy the same data/volume slot, and have different Kubernetes identities.

Choose a procedure supported by the workload and storage provider. Before changing the deployment:

  1. make a recoverable backup or snapshot;
  2. stop or quiesce writers;
  3. copy or restore the data into the target;
  4. verify the target data independently;
  5. record how to return consumers to the source.

Kix detects the replacement but does not perform these steps. The exact copy and verification commands depend on the application, volume provider, and access mode, so they should live in the service’s migration runbook.

An ordinary deployment refuses the pair even when --yes is present:

kix-examples/ live capture
❱ kix deploy how-to-stateful-migration -y
Show outputHide output · 21 lines
Building cluster 'how-to-stateful-migration'...
Cluster how-to-stateful-migration: 9 manifests
Connecting to cluster...
Active activation: how-to-stateful-migration-jk91m5cv9rhy (jk91m5cv...)

Deploy of 'how-to-stateful-migration' stopped: 1 stateful workload replacement(s) require `--accept-migrations`.
Nothing was applied to the cluster.

  Stateful workload replacements (1):
    data/volume (size changed: 5Gi -> 10Gi):
      - PersistentVolumeClaim/media-v1@data
      + PersistentVolumeClaim/media-v2@data

  What happens on deploy:
    - PersistentVolumeClaim/media-v1@data is absent from the new build; without `--prune`, it is kept on the cluster as an orphan.
    - Kix does not copy data between stateful workloads. PersistentVolumeClaim/media-v2@data will see only data already present in its storage.

  Next:
    Prepare or migrate your data, then run the deploy with `--accept-migrations`:
      kix deploy how-to-stateful-migration --accept-migrations
(exit code: 1)

--yes skips the general deploy confirmation. It does not acknowledge data loss risk.

After the data has been migrated and verified, repeat the API-server dry run with the separate acknowledgement:

kix-examples/ live capture
❱ kix deploy how-to-stateful-migration --accept-migrations --dry-run -y
Show outputHide output · 30 lines
Building cluster 'how-to-stateful-migration'...
Cluster how-to-stateful-migration: 9 manifests
Connecting to cluster...
Active activation: how-to-stateful-migration-jk91m5cv9rhy (jk91m5cv...)

Stateful workload replacements (1, accepted with `--accept-migrations`):
    data/volume (size changed: 5Gi -> 10Gi):
      - PersistentVolumeClaim/media-v1@data
      + PersistentVolumeClaim/media-v2@data
  Without `--prune`, PersistentVolumeClaim/media-v1@data is kept as an orphan; with `--prune` (or the operator), it is deleted after the apply.
  Kix does not copy data; PersistentVolumeClaim/media-v2@data sees only data already present in its storage.

  data
    ~ volume 1.0.0 (1 changed, 1 added, 1 removed)
      + PersistentVolumeClaim/media-v2@data
      - PersistentVolumeClaim/media-v1@data
      ~ PackageInstance/volume@data
          ~ $.metadata.annotations.kix.run/root:
              old: "media-v1"
              new: "media-v2"

  Plan: 1 updated, 2 unchanged
  Resources: 3 real content, 0 dep-affected
  1 orphaned (kept; `kix deploy --prune` or `kix gc` deletes them)
    - PersistentVolumeClaim/media-v1@data

Not checked by any preview: whether Pods start, pull their images, and pass their probes.

Objects: 3 written, 0 deleted (sha256:7e719e026b5e2b2409ad68491197f9f2cc6bcbf701fa2e57d0abd52d07f3cf4a)
(exit code: 2)

--accept-migrations only allows the deployment to continue. It does not copy data or verify that the target contains it. The warning about an empty target is literal when the out-of-band migration has not happened.

Review the rest of the deployment plan. Do not add --prune while the source PVC is still part of the rollback plan. Pruning has no separate safeguard for stateful resources. Once the source PVC becomes an orphan, Kix deletes it like any other orphan.

Run the acknowledged deployment without --dry-run:

kix-examples/
❱ kix deploy how-to-stateful-migration --accept-migrations

Confirm the application is using the target and validate its data before retiring the source. Remove the old PVC only after the recovery window and according to the storage provider’s reclaim policy.

See Preview changes with kix plan and kix diff for the ordinary diff workflow.