kubernetes/kops · error
reconcile is not supported with terraform
Error message
reconcile is not supported with terraform
What it means
RunReconcileCluster rejects the terraform target up front: `kops reconcile cluster` performs a sequence of live updates and rolling restarts against the running cluster, which is incompatible with generating terraform output. When CoreUpdateClusterOptions.Target is cloudup.TargetTerraform (i.e. `--target terraform` was effectively set) the command returns this error instead of running. It is an intentional, unconditional guard, not a runtime failure.
Source
Thrown at cmd/kops/reconcile_cluster.go:126
// viper.BindPFlag("lifecycle-overrides", cmd.Flags().Lookup("lifecycle-overrides"))
// viper.BindEnv("lifecycle-overrides", "KOPS_LIFECYCLE_OVERRIDES")
// cmd.RegisterFlagCompletionFunc("lifecycle-overrides", completeLifecycleOverrides)
// cmd.Flags().BoolVar(&options.Prune, "prune", options.Prune, "Delete old revisions of cloud resources that were needed during an upgrade")
// cmd.Flags().BoolVar(&options.IgnoreKubeletVersionSkew, "ignore-kubelet-version-skew", options.IgnoreKubeletVersionSkew, "Setting this to true will force updating the kubernetes version on all instance groups, regardles of which control plane version is running")
// cmd.Flags().BoolVar(&options.Reconcile, "reconcile", options.Reconcile, "Reconcile the cluster by rolling the control plane and nodes sequentially")
return cmd
}
// ReconcileCluster updates the cluster to the desired state, including rolling updates where necessary.
// To respect skew policy, it updates the control plane first, then updates the nodes.
// "update" is probably now smart enough to automatically not update the control plane if it is already at the desired version,
// but we do it explicitly here to be clearer / safer.
func RunReconcileCluster(ctx context.Context, f *util.Factory, out io.Writer, options *ReconcileClusterOptions) error {
c := &options.CoreUpdateClusterOptions
if c.Target == cloudup.TargetTerraform {
return fmt.Errorf("reconcile is not supported with terraform")
}
if !c.Yes {
// A reconcile without --yes is the same as a dry run
opt := *c
if _, err := RunCoreUpdateCluster(ctx, f, out, &opt); err != nil {
return err
}
return nil
}
fmt.Fprintf(out, "Updating control plane configuration\n")
{
opt := *c
opt.InstanceGroupRoles = []string{
string(kops.InstanceGroupRoleAPIServer),
string(kops.InstanceGroupRoleControlPlane),
}View on GitHub (pinned to 4c8573c808)
Solutions
- Remove the terraform target (set Target to "direct" or leave it empty) in the ReconcileClusterOptions before calling RunReconcileCluster.
- If you need terraform-managed infrastructure, run `kops update cluster --target terraform` instead of reconcile, and apply the plan with terraform; use reconcile only for direct in-place updates.
- In wrapper scripts, ensure flags meant for `kops update` (especially --target) are not forwarded to `kops reconcile cluster`.
- If reconcile must support terraform in your workflow, file/upvote an upstream kOps feature request — it is explicitly unsupported today.
Example fix
// before
opt := &ReconcileClusterOptions{}
opt.CoreUpdateClusterOptions.Target = cloudup.TargetTerraform
err := RunReconcileCluster(ctx, f, out, opt) // "reconcile is not supported with terraform"
// after
opt := &ReconcileClusterOptions{}
opt.CoreUpdateClusterOptions.Target = "direct"
err := RunReconcileCluster(ctx, f, out, opt) Defensive patterns
Strategy: validation
Validate before calling
if options.CoreUpdateClusterOptions.Target == cloudup.TargetTerraform {
return errors.New("use `kops update cluster --target terraform` instead of reconcile")
}
err := RunReconcileCluster(ctx, f, out, options) Try / catch
err := RunReconcileCluster(ctx, f, out, options)
if err != nil && strings.Contains(err.Error(), "reconcile is not supported with terraform") {
// fall back to update flow for terraform users
return RunCoreUpdateCluster(ctx, f, out, &options.CoreUpdateClusterOptions)
}
return err Prevention
- Never set Target on ReconcileClusterOptions; leave it at its default (direct).
- Keep `--target terraform` flags in update-command-only code paths; don't share a flag set between update and reconcile.
- If you manage infrastructure with terraform, model your pipeline as: kops update --target terraform + terraform apply; use reconcile only for direct targets.
- Audit wrapper scripts for forwarded update flags before calling reconcile.
When it happens
Trigger: Invoking reconcile with a configuration whose update target is terraform — e.g. programmatically building ReconcileClusterOptions with CoreUpdateClusterOptions.Target = cloudup.TargetTerraform, or wrapping/reusing update flags that had `--target terraform` set. Note the reconcile CLI currently does not expose a --target flag, so this mainly occurs in code that embeds the options.
Common situations: Scripts or tooling that construct shared update options (defaulting Target to terraform) and then call RunReconcileCluster; refactored automation reusing the update command's flag set for reconcile; copying update-command invocation patterns (update --target terraform) onto the reconcile command.
Related errors
- cloud provider %v does not support the terraform target
- cloud provider Azure requires the AzureTerraform feature fla
- Error too many '=' (%d) in %s
- at least one channel URL is required
- building menu for %q: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/019ff55f78793454.
Report an issue: GitHub.