Argo CD v3.4.9 - Resource Health and Sync Fixes


Argo CD v3.4.9 was published on 14 September 2026. It is a final patch on the 3.4 line, built from backports. The change that matters in production is health reporting: a suspended FlinkDeployment, a Crossplane managed resource that is still provisioning, and a KubeVirt VirtualMachine declared stopped now get a status that matches the desired spec.

The full release notes and downloads are on the GitHub release page. The compare from v3.4.8 to v3.4.9 is the full changelog.

Commit 8d84b9380186ef6e1b694c718128ddb4b4cbb5ee reports a suspended FlinkDeployment as Healthy. The note cites 26818, takes the change from pull request 28995, and backports it as pull request 29527. Suspension is a steady state when the spec asks for it. Before this patch, application health did not call that state Healthy, so a paused streaming job looked like a failed sync.

The check does not record who set suspend. Paging on application health stops firing for a declared pause, and the pause disappears as a red application. If suspend is how the pipeline is controlled, read the FlinkDeployment status. Application health is no longer a proxy for a running job.

Commit b938a5e7238c5993534156acdd39953d0aab2bc0 marks a KubeVirt VirtualMachine declared stopped as Healthy. Pull request 29664 is the source, and pull request 29666 is the 3.4 backport. A virtual machine whose spec says stopped was failing the health check, so clusters that keep guests stopped on purpose showed unhealthy applications for a desired condition. Healthy means the object matches stopped. It does not mean a guest is running.

Commit 4e0f6b78ce57547415eaac042a35a29f7fa0345c makes Crossplane managed resources report Progressing, not Healthy, while provisioning is still underway. Issue 29381, source pull request 29382, backport 29521. A managed resource could look Healthy before the cloud API finished creating it, so callers that treated Healthy as permission to continue could move on too early. Those objects now stay Progressing until provisioning completes. The first apply, and any reconcile that has not settled, spends longer in Progressing. Alerts on Progressing get noisier during create. Alerts that treat Healthy as ready get a stricter signal.

Commit fb9431d44e8f61fe0b156a1abb9289b9d85dbe2c ignores GRPCRoute conditions whose observedGeneration is stale. Cited as 28086, source pull request 28087, backport 29518. A Gateway API condition names the generation it was written for. After the route spec moves on, that older condition is not evidence about the new spec. The check skips it, so a route no longer inherits a verdict from status the controller has not rewritten yet.

Commit 51edefdfb252547d408b70da03fceb78a3e0e387 handles the GrafanaFolder negative-polarity condition. Cited as 29395, source pull request 29397, backport 29523. The usual check treats status True as success. A negative polarity condition is healthy when status is False, so folder health was following the wrong value. The bundled check now uses the polarity GrafanaFolder publishes. A copied script that still assumes True means success can disagree with that result.

Commit bfd48bd87729d1675509d89cf9eeb41d83d6a967 cleans the repository when the revision changes. Source pull request 28771, backport 29485. A revision change that left the previous checkout in place could feed leftover files into manifest generation, which matters when the two revisions do not share a file tree. The patch cleans the checkout during the switch. It does not change which revision is selected.

Commit 182c837b67b7176e03342b19e0a7d23a4da347af sets operationState correctly on sync retry. Cited as 26530, source pull request 28778, backport 29432, from omkar619-dev. Retry left operation state inconsistent, so the API and the UI could show a phase that was not the one running. Clients that poll operationState were acting on those values. The patch writes the fields on the retry path.

Two UI fixes sit in the same changelog and do not change reconciliation. Commit ae7133151cd1ad803455a18a810c7a091de09b69 guards the SSO redirect so a 401 cannot enter a retry loop (pull request 28807, backport 29632). Commit 38b5adf870e5aa0521a0a2e2638af11cf087a518 uses the hydrateTo branch name when that field is set (pull request 29562, backport 29566, from crenshaw-dev). The UI was showing some other branch.

v3.4.9 stays on minor 3.4. Anyone coming from a different minor version should read the upgrading overview. From 3.4.8, the differences are the health and sync fixes above. An application that was Healthy only because a Crossplane managed resource was still provisioning will return to Progressing until that work finishes. An application that was unhealthy only because a FlinkDeployment was suspended, or a VirtualMachine was declared stopped, will go Healthy with no spec edit.

The release page links an official blog post as the breakdown for this release. That URL is the v3.0 release candidate article. It does not describe 3.4.9. Use the GitHub release page and the compare link for this patch.

Images are signed with cosign. Provenance for images and CLI binaries meets SLSA Level 3. Verification steps are on the signed release assets page.

The quick start installs this tag with server side apply:

kubectl create namespace argocd
kubectl apply -n argocd --server-side --force-conflicts -f https://raw.githubusercontent.com/argoproj/argo-cd/v3.4.9/manifests/install.yaml

The HA manifest is the same command against https://raw.githubusercontent.com/argoproj/argo-cd/v3.4.9/manifests/ha/install.yaml. The flags --server-side and --force-conflicts are in that snippet. They matter when an older client side apply still owns fields the manifest has to change.