Git, CI/CD & GitOpsLXXXI · Synced versus HealthySyncedVsHealthy
What Synced means — desired state matches actual state
What you'll learn
- Define Synced as the structural equivalence of Git and cluster state at the manifest level
- Identify what a controller actually compares during a sync-status check
- Distinguish a successful sync from a sustained Synced condition
- Read the Sync status block from argocd app get and from the Application CR
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
Synced is the first of two orthogonal questions every GitOps controller answers on every reconciliation tick. The question is structural: do the declarative objects on the cluster match the declarative objects rendered from Git? The answer is yes, no, or unknown - and it is computed by a diff, not by a probe.
A workload can be Synced and still be wrong. A workload can be OutOfSync and still be functioning. Synced is a property of the manifests, not of the behaviour the manifests describe. Treating it as a health signal is the most common mistake operators make when they first adopt GitOps.
How a controller computes Sync
Argo CD and Flux answer the Sync question the same way at a high level. Each controller renders the desired manifests from the source - Git, Helm, Kustomize - compares the rendered manifests to the live objects on the cluster, and reports the diff. If the diff is empty, the application is Synced. If the diff is non-empty, the application is OutOfSync.
flowchart LR
G["Git: manifests"] -->|"render"| R["Rendered manifests"]
R -->|"diff"| D["Diff result"]
L["Live cluster objects"] -->|"observe"| D
D -->|"empty"| S["Synced"]
D -->|"non-empty"| O["OutOfSync"]
The diff is structural. The controller compares spec fields, labels, annotations, owner references - everything except status. A Deployment whose spec.replicas in Git is 3 and whose live Deployment has spec.replicas: 3 is Synced even if all three pods are crash-looping. The controller does not read the pods to answer the Sync question; it reads the Deployment object.
What Synced is not
Synced is not a deployment success signal. Synced is not a workload availability signal. Synced is not a configuration-correctness signal. A controller reports Synced when the manifests agree; the cluster can still be in a state where the manifests agree but the workload is broken.
- Synced does not mean “the latest commit is applied”. A controller with self-heal disabled can be OutOfSync for hours after a change.
- Synced does not mean “the previous sync succeeded”. An OutOfSync application whose last sync succeeded is a different condition than an OutOfSync application whose last sync failed.
- Synced does not mean “Git is the truth”. A manual
kubectl editfollowed by a disable of self-heal produces a Synced application whose cluster does not match Git, until the next reconciliation tick.
The Synced status is a snapshot of the most recent comparison, not a promise about the future.
The Sync block in the operator CLI
The Sync status surfaces in two places operators use daily. The first is the Argo CD CLI. The second is the Application custom resource on the cluster.
argocd app get "$APP" --show-operation
The output includes a Sync Status line, a Last Sync line, and - when --show-operation is passed - the running or finished operation with phase, message, and the sync result. The relevant fields for the Synced question are Sync Status: Synced or Sync Status: OutOfSync, the revision the controller is tracking, and the timestamp of the last successful apply.
The second surface is the cluster itself. Argo CD stores the Sync status in the Application CR’s status.sync.status field. Flux stores an equivalent value in the Kustomization or HelmRelease status.
kubectl get application "$APP" -n argocd -o yaml
Look at status.sync.status, status.sync.revision, and status.conditions. The CR is what the controller itself uses; the CLI is a formatted view of it. When the CLI and the CR disagree, the CR is authoritative - the CLI may be reading a cached projection.
Production discipline
The production framing of Synced has three rules that prevent the structural-versus-behavioural confusion:
- Synced means manifests agree, not that workloads are healthy. A green Sync indicator is a precondition for health, not a guarantee of it. Always read both.
- Sync status is a snapshot. The status was true at the timestamp the controller recorded. A manual
kubectl editafter that timestamp invalidates it without alerting. - OutOfSync is a state to investigate, not a state to suppress. Disabling diff notifications to keep the dashboard quiet is how production drifts without anyone noticing.
Cross-course references
- Linux for Production Sysadmins - Part XXII (ProcessSupervision) covers the gap between “the unit file is loaded” and “the service is responding”, which is the same structural-versus-behavioural distinction.
- Ansible for Production Sysadmins - Part XLIV (Idempotency) covers the gap between “the playbook ran” and “the system is in the desired state”.
- Terraform for Production Sysadmins - Parts XXVIII (Plan) cover the gap between “the plan is empty” and “the resource is healthy”.
Quiz
Knowledge check · 4 questions
Q1. An Argo CD application shows Sync Status: Synced. The workload it manages is returning 500s on every request. Which statement is correct?
Q2. An application can be OutOfSync even when its last sync operation succeeded.
Q3. Name the two fields the GitOps controller compares to compute Synced, and name the field category it deliberately excludes from the comparison.
Q4. Diagnose why the dashboard says Synced while the application is serving stale responses.
A team uses Argo CD to manage a payment-service Deployment. An engineer commits a new version with an updated container image tag and a new environment variable. Argo CD syncs successfully and the dashboard shows Sync Status: Synced within minutes. Thirty minutes later, the on-call engineer is paged because payment-service is serving stale responses from the previous version. The Deployment spec, including the image tag, matches Git. The pods, however, are running the previous image.
Passing score: 75%. Answers are checked in this browser.