kubernetes/kops · error

lifecycle set to ExistsAndValidates, but object did not matc

Error message

lifecycle set to ExistsAndValidates, but object did not match

What it means

With lifecycle ExistsAndValidates, if the actual object exists but its fields differ from desired, Render builds a change list, prints the diffs to stderr, and then fails with this error — the assertion is that the object exists AND is unchanged. ExistsAndWarnIfChanges is the lenient variant that only warns.

Source

Thrown at upup/pkg/fi/context.go:182

				taskName := getTaskName(e)
				fmt.Fprintf(b, "Object from different phase did not match, problems possible:\n")
				fmt.Fprintf(b, "  %s/%s\n", taskName, "?")
				for _, change := range changeList {
					lines := strings.Split(change.Description, "\n")
					if len(lines) == 1 {
						fmt.Fprintf(b, "  \t%-20s\t%s\n", change.FieldName, change.Description)
					} else {
						fmt.Fprintf(b, "  \t%-20s\n", change.FieldName)
						for _, line := range lines {
							fmt.Fprintf(b, "  \t%-20s\t%s\n", "", line)
						}
					}
				}
				fmt.Fprintf(b, "\n")
				b.WriteTo(out)

				if lifecycle == LifecycleExistsAndValidates {
					return fmt.Errorf("lifecycle set to ExistsAndValidates, but object did not match")
				}
				// Warn, but then we continue
				return nil
			}
		}
	}

	if _, ok := c.Target.(*DryRunTarget[T]); ok {
		return c.Target.(*DryRunTarget[T]).Render(a, e, changes)
	}

	v := reflect.ValueOf(e)
	vType := v.Type()

	targetType := reflect.ValueOf(c.Target).Type()

	// Probe renderers with literal method names only: enumerating the method set or passing a
	// variable name to MethodByName would disable linker pruning of every unused exported method.

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Revert the out-of-band change so the object matches the kops manifest, then re-run.
  2. Run `kops update cluster` with the default lifecycle to apply the desired state, then re-run the ExistsAndValidates check.
  3. Review the printed field-by-field diff on stderr to see exactly which fields drifted.

Example fix

# before (object drifted)
kops update cluster <name> --lifecycle-existence-checks  # fails
# after
kops update cluster <name>   # apply desired state
kops update cluster <name> --lifecycle-existence-checks  # now passes
Defensive patterns

Strategy: validation

Validate before calling

// pre-run drift check
out, _ := exec.Command("kops", "update", "cluster", name, "--dry-run").Output()
if strings.Contains(string(out), "did not match") { reconcileFirst() }

Try / catch

err := kopsUpdate(...)
if err != nil && strings.Contains(err.Error(), "ExistsAndValidates, but object did not match") {
    klog.Errorf("drift detected, review stderr diff: %v", err)
}

Prevention

When it happens

Trigger: A task rendered with lifecycle ExistsAndValidates where buildChangeList reports non-empty differences — e.g. an IAM policy, security group rule, or ASG was modified out-of-band — during phased updates (`kops update cluster --phase ...`) or --lifecycle-existence-checks runs.

Common situations: Manual console edits to cloud resources (tag changes, instance-type tweaks) between kops runs; kops version upgrade changing generated spec fields; another automation tool mutating the same resource; strict CI validation of cluster drift.

Related errors


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