The Controller with Field Ownership Conflict Resolution Pattern for Multi-Manager Coexistence: When Two Controllers Legitimately Own Overlapping Fields

2026-08-28

Server-Side Apply solved the "who wrote this field?" problem by tracking ownership per field. But what happens when two controllers legitimately need to write the same field? A HorizontalPodAutoscaler adjusts spec.replicas, but so does your GitOps operator reconciling from Git. Both are correct. Both will fight forever unless you resolve the conflict deliberately.

The naive answer — "last writer wins" — creates the reconciliation loop from hell. Argo CD sets replicas to 3 (from Git). HPA sets it to 7 (from load). Argo detects drift, sets it back to 3. HPA sets it to 7. Repeat every few seconds until your API server melts and your pods flap.

The pattern: Explicitly designate a field owner per field, and teach the non-owner to relinquish ownership rather than fight for it. Three mechanisms make this work:

Real-world example: Argo CD's ignoreDifferences configuration for HPA-managed deployments:

ignoreDifferences:
  - group: apps
    kind: Deployment
    jsonPointers:
      - /spec/replicas

This tells Argo: "don't include spec.replicas in your apply, and don't flag drift on it." HPA owns the field. Argo owns everything else. No fight.

Rule of thumb: If two controllers reconcile the same field with a period of P seconds each, and neither yields, expect roughly 2/P writes per second forever — and each write costs at least one etcd fsync. At P=5s across 100 deployments, that's 40 writes/sec of pure waste, plus API server CPU for validation and admission. Enough to noticeably degrade cluster performance.

The design principle: ownership must be modeled explicitly, not inferred from who wrote last. The managedFields metadata is your source of truth; use it to detect conflicts before they become reconciliation storms. When conflict is detected, someone must yield — and that decision belongs in configuration, not in a race condition.

Key Takeaway: When two controllers legitimately need the same field, designate an owner explicitly and teach the other to omit the field entirely — anything less creates an infinite reconciliation war that burns etcd and API server capacity for no benefit.

All newsletters