kubernetes/kops · error

kops version older than last used to update the cluster

Error message

kops version older than last used to update the cluster

What it means

Run() enforces downgrade protection: if the kops-version-updated marker records a version greater than the running kops binary's version, Run refuses to proceed. Updating a cluster with an older kops than the last one that touched it can silently revert resources, so it errors out and points to --allow-kops-downgrade.

Source

Thrown at upup/pkg/fi/cloudup/apply_cluster.go:294

	if !c.AllowKopsDowngrade {
		kopsVersionUpdatedBytes, err := configBase.Join(registry.PathKopsVersionUpdated).ReadFile(ctx)
		if err == nil {
			kopsVersionUpdated := strings.TrimSpace(string(kopsVersionUpdatedBytes))
			version, err := semver.Parse(kopsVersionUpdated)
			if err != nil {
				return nil, fmt.Errorf("error parsing last kops version updated: %v", err)
			}
			if version.GT(semver.MustParse(kopsbase.Version)) {
				fmt.Printf("\n")
				fmt.Printf("%s\n", starline)
				fmt.Printf("\n")
				fmt.Printf("The cluster was last updated by kops version %s\n", kopsVersionUpdated)
				fmt.Printf("To permit updating by the older version %s, run with the --allow-kops-downgrade flag\n", kopsbase.Version)
				fmt.Printf("\n")
				fmt.Printf("%s\n", starline)
				fmt.Printf("\n")
				return nil, fmt.Errorf("kops version older than last used to update the cluster")
			}
		} else if err != os.ErrNotExist {
			return nil, fmt.Errorf("error reading last kops version used to update: %v", err)
		}
	}

	cloud := c.Cloud

	err = validation.DeepValidate(c.Cluster, c.InstanceGroups, true, c.Clientset.VFSContext(), cloud)
	if err != nil {
		return nil, err
	}

	if cluster.Spec.KubernetesVersion == "" {
		return nil, fmt.Errorf("KubernetesVersion not set")
	}
	if cluster.Spec.DNSZone == "" && cluster.PublishesDNSRecords() {
		return nil, fmt.Errorf("DNSZone not set")

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Upgrade kops to at least the recorded version (kops get cluster shows it; or install the latest release) and rerun.
  2. If downgrading intentionally, pass --allow-kops-downgrade to the update command.
  3. Align CI tooling versions: check `kops version` against the cluster's last-updated version before running updates.

Example fix

// before
kops update cluster mycluster.example.com --yes
// after
kops update cluster mycluster.example.com --yes --allow-kops-downgrade
Defensive patterns

Strategy: validation

Validate before calling

if kopsVersionUpdated.GT(semver.MustParse(kopsbase.Version)) && !opts.AllowKopsDowngrade {
    return fmt.Errorf("upgrade kops to >= %s or pass --allow-kops-downgrade", kopsVersionUpdated)
}

Prevention

When it happens

Trigger: Running `kops update cluster` (or RunUpdateCluster/apply) with a binary older than the version recorded in <configBase>/kops-version-updated, without passing --allow-kops-downgrade.

Common situations: CI runner or local machine with a stale pinned kops binary after the cluster was updated by a newer release; pinning kops in a Dockerfile to an old tag; kops auto-updated elsewhere (e.g. kops update container) then an older tool runs the next update.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/34eec936eb5856b9. Report an issue: GitHub.