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
- Revert the out-of-band change so the object matches the kops manifest, then re-run.
- Run `kops update cluster` with the default lifecycle to apply the desired state, then re-run the ExistsAndValidates check.
- 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
- Treat kops-managed resources as immutable outside kops.
- Re-run `kops update cluster` after kops upgrades to absorb generated-spec changes.
- Read the stderr field diff Render prints to locate drifted fields quickly.
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
- lifecycle set to ExistsAndValidates, but object was not foun
- incorrect syntax for lifecyle-overrides, correct syntax is T
- unknown lifecycle %q, available lifecycle: %s
- duplicate scope: %q
- shutdown already in progress
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/5b9b42003cf38b03.
Report an issue: GitHub.